Home | History | Annotate | Download | only in layout
      1 /*
      2  *******************************************************************************
      3  *
      4  *   Copyright (C) 1999-2007, International Business Machines
      5  *   Corporation and others.  All Rights Reserved.
      6  *
      7  *******************************************************************************
      8  *   file name:  LEFontInstance.cpp
      9  *
     10  *   created on: 02/06/2003
     11  *   created by: Eric R. Mader
     12  */
     13 
     14 #include "LETypes.h"
     15 #include "LEScripts.h"
     16 #include "LEFontInstance.h"
     17 #include "LEGlyphStorage.h"
     18 
     19 U_NAMESPACE_BEGIN
     20 
     21 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance)
     22 
     23 LECharMapper::~LECharMapper()
     24 {
     25     // nothing to do.
     26 }
     27 
     28 LEFontInstance::~LEFontInstance()
     29 {
     30     // nothing to do
     31 }
     32 
     33 const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit,
     34                                                        le_int32 script, LEErrorCode &success) const
     35 {
     36     if (LE_FAILURE(success)) {
     37         return NULL;
     38     }
     39 
     40     if (chars == NULL || *offset < 0 || limit < 0 || *offset >= limit || script < 0 || script >= scriptCodeCount) {
     41         success = LE_ILLEGAL_ARGUMENT_ERROR;
     42         return NULL;
     43     }
     44 
     45     *offset = limit;
     46     return this;
     47 }
     48 
     49 void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count,
     50                                       le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const
     51 {
     52     le_int32 i, out = 0, dir = 1;
     53 
     54     if (reverse) {
     55         out = count - 1;
     56         dir = -1;
     57     }
     58 
     59     for (i = offset; i < offset + count; i += 1, out += dir) {
     60         LEUnicode16 high = chars[i];
     61         LEUnicode32 code = high;
     62 
     63         if (i < offset + count - 1 && high >= 0xD800 && high <= 0xDBFF) {
     64             LEUnicode16 low = chars[i + 1];
     65 
     66             if (low >= 0xDC00 && low <= 0xDFFF) {
     67                 code = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
     68             }
     69         }
     70 
     71         glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth);
     72 
     73         if (code >= 0x10000) {
     74             i += 1;
     75             glyphStorage[out += dir] = 0xFFFF;
     76         }
     77     }
     78 }
     79 
     80 LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
     81 {
     82     return mapCharToGlyph(ch, mapper, TRUE);
     83 }
     84 
     85 LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
     86 {
     87     LEUnicode32 mappedChar = mapper->mapChar(ch);
     88 
     89     if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) {
     90         return 0xFFFF;
     91     }
     92 
     93     if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) {
     94         return canDisplay(mappedChar)? 0x0001 : 0xFFFF;
     95     }
     96 
     97     return mapCharToGlyph(mappedChar);
     98 }
     99 
    100 le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const
    101 {
    102     return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0;
    103 }
    104 
    105 float LEFontInstance::xUnitsToPoints(float xUnits) const
    106 {
    107     return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM();
    108 }
    109 
    110 float LEFontInstance::yUnitsToPoints(float yUnits) const
    111 {
    112     return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM();
    113 }
    114 
    115 void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const
    116 {
    117     points.fX = xUnitsToPoints(units.fX);
    118     points.fY = yUnitsToPoints(units.fY);
    119 }
    120 
    121 float LEFontInstance::xPixelsToUnits(float xPixels) const
    122 {
    123     return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm();
    124 }
    125 
    126 float LEFontInstance::yPixelsToUnits(float yPixels) const
    127 {
    128     return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm();
    129 }
    130 
    131 void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const
    132 {
    133     units.fX = xPixelsToUnits(pixels.fX);
    134     units.fY = yPixelsToUnits(pixels.fY);
    135 }
    136 
    137 void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
    138 {
    139     pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX();
    140     pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY();
    141 }
    142 
    143 le_int32 LEFontInstance::getLineHeight() const
    144 {
    145     return getAscent() + getDescent() + getLeading();
    146 }
    147 
    148 U_NAMESPACE_END
    149 
    150