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