Changeset 100:0ea4a3e651ae

Show
Ignore:
Timestamp:
11/15/08 12:39:14 (2 months ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
branch:
default
Message:

There is now a position marker for text editing.

Changed the way fonts are configured. Actually, not much of the new way exists yet.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • data/conf/gui.mtt

    r99 r100  
    1717<WidgetData|floating={0:[0x8200,13,6,14],1:["text","button","blank"]}> 
    1818<WidgetData|text={0:[0x4032]}> 
    19 <WDims|content=[736,221,272,79]> 
    20 <WDims|root=[6,736,50,6,580,6]> 
    21 <WDims|floating=[25,0,103,27,572,26,74,74,242,128,168,93]> 
    2219{Basic} 
    2320<WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}> 
  • data/conf/options.mtt

    r98 r100  
    1111<int|lcdFilter=2> 
    1212<int|renderMode=0x30000> 
     13<char[]|defaultFont="/usr/share/fonts/X11/Type1/n019003l.pfb"> 
     14!<char[]|defaultFont="/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"> 
     15<int|defaultSize=16> 
    1316 
    1417{VideoOptions} 
  • mde/font/FontTexture.d

    r98 r100  
    6161    } 
    6262     
    63      
    6463    /** Cache informatation for rendering a block of text. 
    6564     * 
     
    7473         
    7574        cache.cacheVer = cacheVer; 
     75    cache.w = cache.h = 0;      // reset 
    7676         
    7777        /* Convert the string to an array of character codes (which is equivalent to decoding UTF8 
     
    151151     *  x = Smaller x-coordinate of position 
    152152     *  y = Smaller y-coordinate of position 
    153      *  col =   Text colour (note: currently limited to black or white) */ 
    154     void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col ) { 
     153     *  col =   Text colour (note: currently limited to black or white) 
     154     *  index = Index of edit position, or size_t.max if no idet position. */ 
     155    void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col, size_t index) { 
    155156        updateCache (face, str, cache); // update if necessary 
    156157        debug scope (failure) 
     
    160161        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
    161162         
    162         drawCacheImpl (cache, x, y, col); 
     163        drawCacheImpl (face, cache, x, y, col, index); 
    163164    } 
    164165    /** A variation of drawCache, for transparent text. 
     
    174175     * 
    175176     * The overhead of the transparency is minimal. */ 
    176     void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col/+ = Colour.WHITE+/) { 
     177    void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col, size_t index) { 
    177178        updateCache (face, str, cache); // update if necessary 
    178179        debug scope (failure) 
     
    183184        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
    184185         
    185         drawCacheImpl (cache, x, y, col); 
    186     } 
    187     
    188     private void drawCacheImpl (ref TextBlock cache, int x, int y, Colour col) { 
     186   drawCacheImpl (face, cache, x, y, col, index); 
     187    } 
     188     
     189    private void drawCacheImpl (FT_Face face, ref TextBlock cache, int x, int y, Colour col, size_t index) { 
    189190        if (DerelictGL.availableVersion() >= GLVersion.Version14) { 
    190191            glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); 
     
    217218            glEnd (); 
    218219        } 
    219          
    220         glDisable(GL_TEXTURE_2D); 
     220    glDisable(GL_TEXTURE_2D); 
    221221        glDisable(GL_BLEND); 
     222     
     223    if (index <= cache.chars.length) {  // draw edit position 
     224        int x1; 
     225        if (index == 0) 
     226        x1 = x + 1; 
     227        else { 
     228        auto c = cache.chars[index-1]; 
     229        x1 = x + c.xPos + c.ga.advanceX; 
     230        } 
     231        glColor3f(col.r, col.g, col.b); 
     232        glRecti(x1 - 1, y, x1, y + (face.size.metrics.height >> 6)); 
     233    } 
    222234    } 
    223235     
     
    447459     * lcdFilter should come from enum FT_LcdFilter: 
    448460     * FT_LCD_FILTER_NONE (0), FT_LCD_FILTER_DEFAULT (1), FT_LCD_FILTER_LIGHT (2) */ 
    449     mixin (impl!("int renderMode, lcdFilter;")); 
     461    mixin (impl!("int renderMode, lcdFilter, defaultSize; char[] defaultFont;")); 
     462     
     463    void validate() { 
     464    } 
    450465     
    451466    static this() { 
     
    470485 * Struct should be stored externally and updated via references. */ 
    471486struct TextBlock { 
    472     CharCache[] chars;  // All chars. They hold x & y pos. info, so don't need to know about lines. 
    473     int cacheVer = -1;  // this is checked on access, and must equal for cache to be valid
    474     int w, h;       /// Size of the block. Likely the only fields of use outside the library. 
     487    CharCache[] chars;  /// All chars. They hold x & y pos. info, so don't need to know about lines. 
     488    int cacheVer = -1;  /// Checked on access; must equalFontTexture.cacheVer or the cache is rebuilt
     489    int w, h;       /// Size of the block. 
    475490} 
    476491struct CharCache { 
    477     GlyphAttribs* ga;   // character 
    478     int xPos, yPos; // x,y position 
    479 } 
     492    GlyphAttribs* ga;   /// The character 
     493    int xPos, yPos; /// Character's x,y position 
     494} 
  • mde/font/font.d

    r98 r100  
    2222import mde.font.exception; 
    2323 
    24 import mde.file.mergetag.Reader; 
    25 import mde.file.mergetag.DataSet; 
    26 import mde.setup.paths; 
    2724import mde.setup.exception;     // InitStage stuff 
    2825 
    2926import derelict.freetype.ft; 
    3027 
    31 import mde.file.deserialize; 
    3228import tango.stdc.stringz; 
    3329import Util = tango.text.Util; 
     
    4743 *  
    4844 * Note: it is not currently intended to be thread-safe. */ 
    49 class FontStyle : IDataSection 
     45class FontStyle 
    5046{ 
    5147    //BEGIN Static: manager 
     
    5652        } 
    5753         
    58         /** Load the freetype library with settings from the file fileName. */ 
    59         private const fileName = "fonts"; 
     54        /** Load the freetype library with settings from options. */ 
    6055        StageState initialize () { 
    6156            if (FT_Init_FreeType (&library)) 
     
    6762            if (maj != 2 || min != 3) { 
    6863                logger.warn ("Using an untested FreeType version: {}.{}.{}", maj, min, patch); 
    69                 logger.info ("The only tested version of freetype is 2.3.5"); 
     64                logger.info ("The only tested version of freetype is 2.3"); 
    7065            } 
    7166             
     
    8782            } 
    8883             
    89             /* Load font settings 
    90              * 
    91              * Each mergetag section corresponds to a font; each is loaded whether used or not 
    92              * (however the actual font files are only loaded on use). A fallback id must be 
    93              * provided in the header which must match a loaded font name; if a non-existant font 
    94              * is requested a warning will be logged and this font returned. */ 
    95             char[] fallbackName; 
    96             try { 
    97                 IReader reader; 
    98                 reader = confDir.makeMTReader (fileName, PRIORITY.LOW_HIGH, null, true); 
    99                 reader.dataSecCreator = delegate IDataSection(ID id) { 
    100                     auto f = new FontStyle; 
    101                     fonts[id] = f; 
    102                     return f; 
    103                 }; 
    104                 reader.read; 
    105                  
    106                 // get fallback name 
    107                 char[]* p = "fallback" in reader.dataset.header._charA; 
    108                 if (p is null) 
    109                     throw new fontException ("No fallback font style specified"); 
    110                 fallbackName = *p; 
    111             } catch (NoFileException) { 
    112                 throw new fontException ("No font settings file (fonts.[mtt|mtb])"); 
    113             } catch (Exception e) { 
    114                 throw new fontException ("Reading font settings failed: "~e.msg); 
    115             } 
    116              
    117             // Find the fallback 
    118             FontStyle* p = fallbackName in fonts; 
    119             if (p is null) 
    120                 throw new fontException ("Fallback font style specified is not found"); 
    121             fallback = *p; 
    122             // Load the fallback now, to ensure it's available. 
    123             // Also note that get() doesn't make sure the fallback is loaded before returning it. 
    124             fallback.load; 
    125              
     84            // Load the fallback font; if it throws let exception abort program 
     85        fallback = new FontStyle (fontOpts.defaultFont(), fontOpts.defaultSize()); 
     86         
    12687            return StageState.ACTIVE; 
    12788        } 
     
    13091        StageState cleanup () { 
    13192            // Clear loaded fonts (each has an FT_Face object needing to be freed): 
    132             foreach (fs; fonts) 
     93            /* FIXME 
     94        foreach (fs; fonts) 
    13395                fs.freeFace; 
     96        */ 
    13497             
    13598            FT_Done_FreeType (library); // free the library 
     
    145108          * this function should never fail or throw, in theory (unless out of memory). The 
    146109          * fallback should already be loaded. */ 
    147         FontStyle get(char[] name) { 
    148             FontStyle* p = name in fonts; 
    149             if (p is null) { 
    150                 logger.warn ("Font style "~name~" requested but not found; reverting to the fallback style."); 
    151                 fonts[name] = fallback; // set to prevent another warning getting logged 
    152                 return fallback; 
    153             } 
    154             // Got it, but we need to make sure it's loaded: 
    155             try { 
    156                 p.load; 
    157             } catch (Exception e) { 
    158                 logger.warn ("Font style "~name~" failed to load; reverting to the fallback style."); 
    159                 return fallback; 
    160             } 
    161             return *p; 
     110        FontStyle getDefault () { 
     111        //FIXME: Ddoc, new purpose; rename 
     112            return fallback; 
    162113        } 
    163114         
     
    165116        FT_Library  library; 
    166117        FontTexture fontTex; 
    167         FontStyle[ID]  fonts;      // all font styles known about; not necessarily loaded 
    168         FontStyle   fallback;   // used when requested font isn't in fonts 
     118        //FontStyle[char[]]    fonts;  // loaded fonts, by file name    FIXME: use hash of struct { char[] path; int size; }? 
     119        FontStyle   fallback;   // default & used when requested font can't be loaded 
    169120    } 
    170121    //END Static 
    171      
    172     this() {} 
    173      
    174     //BEGIN Mergetag code 
    175     //NOTE: would it be better not to use a new mergetag file for this? 
    176     //FIXME: revise when gui can set options 
    177     void addTag (char[] tp, ID id, char[] dt) { 
    178         if (tp == "char[]") { 
    179             if (id == "path") 
    180                 path = parseTo!(char[]) (dt); 
    181         } 
    182         else if (tp == "int") { 
    183             if (id == "size") 
    184                 size = parseTo!(int) (dt); 
    185         } 
    186     } 
    187     void writeAll (ItemDelg) {}     // no writing the config for now 
    188     //END Mergetag code 
    189122     
    190123    /** Load the font file. 
     
    193126     * Sharing an FT_Face would require calling FT_Set_Pixel_Sizes each time a glyph is rendered or 
    194127     * swapping the size information (face.size)? */ 
    195     void load (
     128    this (char[] path, int size
    196129    in { 
    197130        assert (library !is null, "font: library is null"); 
     
    207140         */ 
    208141         
    209         if (FT_Set_Pixel_Sizes (face, 0,size)) 
     142        if (FT_Set_Pixel_Sizes (face, 0, size)) 
    210143            throw new fontLoadException ("Unable to set pixel size"); 
    211144         
     
    213146        if (fontTex is null) 
    214147            fontTex = new FontTexture; 
     148     
     149    return this; 
     150    } 
     151     
     152    this (FontStyle font, int size) { 
     153    //FIXME: copy font's face and set new size? 
    215154    } 
    216155     
     
    235174    /** Draw a block of text (may inlcude new-lines). 
    236175     * 
     176     * Params: 
     177     *  x = Top left x-coordinate of text block 
     178     *  y = Top left y-coordinate of text block 
     179     *  str =   Text to render 
     180     *  cache = An (optional) TextBlock used for rendering this text, to save some CPU work. See updateBlock 
     181     *  col =   Colour to render the text; see mde.types.Colour 
     182     *  index = Either the index of the character to draw with an edit cursor or size_t.max. Not 
     183     *      the index within str, but the number of characters, excluding new-lines. 
    237184     * The text block is drawn with top-left corner at x,y. To put the text's baseline at a given 
    238      * y coordinate would require some changes. Line height is fixed based on largest glyph
     185     * y coordinate would require some changes. Line height is fixed (see getLineSeparation)
    239186     * Due to hinter, glyphs are not guaranteed to lie within the "bounding box" defined by cache. 
    240187     * Can be changed to test size of each glyph if necessary. 
     
    248195     * char[] str; 
    249196     * TextBlock strCache; 
    250      * textBlock (x, y, str, strCache); 
     197     * textBlock (x, y, str, strCache, Colour.WHITE); 
    251198     * --------------------------------- 
    252199     * The TextBlock cache will be updated as necessary. Besides the initial update, this will only 
     
    258205     * of a text block is to use a TextBlock cache and update it, either with this function or with 
    259206     * the updateBlock function. */ 
    260     void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col
    261     in { 
    262         assert (face, "FontStyle: face is null"); 
    263     } body { 
    264         try { 
    265             fontTex.drawCache (face, str, cache, x, y, col); 
     207    void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col, size_t index = size_t.max
     208    in { 
     209        assert (face, "FontStyle: face is null"); 
     210    } body { 
     211        try { 
     212            fontTex.drawCache (face, str, cache, x, y, col, index); 
    266213        } catch (Exception e) { 
    267214            logger.warn ("Exception while drawing text: "~e.msg); 
     
    269216    } 
    270217    /** ditto */ 
    271     void textBlock (int x, int y, char[] str, Colour col
     218    void textBlock (int x, int y, char[] str, Colour col, size_t index = size_t.max
    272219    in { 
    273220        assert (face, "FontStyle: face is null"); 
     
    278225            // would be horrible). 
    279226            TextBlock cache; 
    280             fontTex.drawCache (face, str, cache, x, y, col); 
     227            fontTex.drawCache (face, str, cache, x, y, col, index); 
    281228        } catch (Exception e) { 
    282229            logger.warn ("Exception while drawing text: "~e.msg); 
     
    288235     * Set the alpha by calling glColor*() first. See FontTexture.drawCacheA()'s documentation for 
    289236     * details. */ 
    290     void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col)  
    291     in { 
    292         assert (face, "FontStyle: face is null"); 
    293     } body { 
    294         try { 
    295             fontTex.drawCacheA (face, str, cache, x, y, col); 
     237    void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col, size_t index = size_t.max)  
     238    in { 
     239        assert (face, "FontStyle: face is null"); 
     240    } body { 
     241        try { 
     242       fontTex.drawCacheA (face, str, cache, x, y, col, index); 
    296243        } catch (Exception e) { 
    297244            logger.warn ("Exception while drawing text: "~e.msg); 
     
    313260     
    314261private: 
    315     char[]  path;   // path to font file 
    316     int     size;   // font size 
    317      
    318262    FT_Face face; 
    319      
    320     debug(mdeUnitTest) unittest { 
    321         // Don't do a unittest since font relies on loading the freetype library dynamically, 
    322         // normally done by Init. Also font is mostly visual and many problems will be obvious. 
    323     } 
    324263} 
    325  
    326 /+class OptionsFont : Options { 
    327     alias store!(+/ 
  • mde/gui/content/Content.d

    r99 r100  
    226226    } 
    227227     
     228    size_t getEditIndex () { 
     229    size_t i = 0; 
     230    for (size_t p = 0; p < pos; ++p) 
     231        if (!(v[p] & 0x80) || v[p] & 0x40) 
     232        ++i; 
     233    return i; 
     234    } 
     235     
    228236    /// Gives all callbacks the modified value 
    229237    void endEdit () { 
  • mde/gui/renderer/IRenderer.d

    r99 r100  
    9696        colour = Colour (col); 
    9797    } 
     98     
     99    void setIndex (size_t index = size_t.max) { 
     100        this.index = index; 
     101    } 
    98102         
    99103        void getDimensions (out wdsize w, out wdsize h) { 
     
    104108         
    105109        void draw (wdabs x, wdabs y) { 
    106             font.textBlock (x,y, content, textCache, colour); 
     110            font.textBlock (x,y, content, textCache, colour, index); 
    107111        } 
    108112         
    109113        char[] content; 
    110114        TextBlock textCache; 
     115    size_t index; 
    111116        Colour colour; 
    112117        FontStyle font; 
  • mde/gui/renderer/SimpleRenderer.d

    r99 r100  
    3232{ 
    3333    this () { 
    34         defaultFont = FontStyle.get("default")
     34        defaultFont = FontStyle.getDefault
    3535    } 
    3636     
     
    136136        a.content = text; 
    137137    a.colour = Colour (col); 
    138         return a; 
     138    a.index = size_t.max; 
     139    return a; 
    139140    } 
    140141     
  • mde/gui/widget/textContent.d

    r99 r100  
    2424import mde.gui.content.Content; 
    2525 
     26debug { 
     27    import tango.util.log.Log : Log, Logger; 
     28    private Logger logger; 
     29    static this () { 
     30    logger = Log.getLogger ("mde.gui.widget.textContent"); 
     31    } 
     32} 
     33 
    2634 
    2735class TextContentWidget : ATextWidget 
     
    3846    /** On click, request keyboard input. */ 
    3947    int clickEvent (wdabs, wdabs, ubyte, bool state) { 
     48    adapter.setIndex = content.getEditIndex; 
     49    mgr.requestRedraw; 
    4050    return 1;   // get keyboard input via keyEvent 
    4151    } 
    4252     
    4353    void keyEvent (ushort s, char[] i) { 
    44     adapter.setText (content.keyStroke (s, i)); 
    45     adapter.getDimensions (mw, mh); // FIXME: only passively change size: next resize will see new minimal size 
     54    adapter.setText = content.keyStroke (s, i); 
     55    adapter.setIndex = content.getEditIndex; 
     56    adapter.getDimensions (mw, mh); // NOTE: only passively change size: next resize will see new minimal size 
    4657    mgr.requestRedraw; 
    4758    } 
    4859    void keyFocusLost () { 
     60    adapter.setIndex; 
    4961    content.endEdit;    // update other users of content relying on callbacks 
     62    mgr.requestRedraw; 
    5063    } 
    5164