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 19U_NAMESPACE_BEGIN 20 21UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance) 22 23LECharMapper::~LECharMapper() 24{ 25 // nothing to do. 26} 27 28LEFontInstance::~LEFontInstance() 29{ 30 // nothing to do 31} 32 33const 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 49void 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 80LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const 81{ 82 return mapCharToGlyph(ch, mapper, TRUE); 83} 84 85LEGlyphID 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 100le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const 101{ 102 return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0; 103} 104 105float LEFontInstance::xUnitsToPoints(float xUnits) const 106{ 107 return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM(); 108} 109 110float LEFontInstance::yUnitsToPoints(float yUnits) const 111{ 112 return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM(); 113} 114 115void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const 116{ 117 points.fX = xUnitsToPoints(units.fX); 118 points.fY = yUnitsToPoints(units.fY); 119} 120 121float LEFontInstance::xPixelsToUnits(float xPixels) const 122{ 123 return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm(); 124} 125 126float LEFontInstance::yPixelsToUnits(float yPixels) const 127{ 128 return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm(); 129} 130 131void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const 132{ 133 units.fX = xPixelsToUnits(pixels.fX); 134 units.fY = yPixelsToUnits(pixels.fY); 135} 136 137void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const 138{ 139 pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX(); 140 pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY(); 141} 142 143le_int32 LEFontInstance::getLineHeight() const 144{ 145 return getAscent() + getDescent() + getLeading(); 146} 147 148U_NAMESPACE_END 149 150