1/* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26/* 27 ******************************************************************************* 28 * 29 * Copyright (C) 1999-2007, International Business Machines 30 * Corporation and others. All Rights Reserved. 31 * 32 ******************************************************************************* 33 * file name: LEFontInstance.cpp 34 * 35 * created on: 02/06/2003 36 * created by: Eric R. Mader 37 */ 38 39#include "LETypes.h" 40#include "LEScripts.h" 41#include "LEFontInstance.h" 42#include "LEGlyphStorage.h" 43 44U_NAMESPACE_BEGIN 45 46UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEFontInstance) 47 48LECharMapper::~LECharMapper() 49{ 50 // nothing to do. 51} 52 53LEFontInstance::~LEFontInstance() 54{ 55 // nothing to do 56} 57 58const LEFontInstance *LEFontInstance::getSubFont(const LEUnicode chars[], le_int32 *offset, le_int32 limit, 59 le_int32 script, LEErrorCode &success) const 60{ 61 if (LE_FAILURE(success)) { 62 return NULL; 63 } 64 65 if (chars == NULL || *offset < 0 || limit < 0 || *offset >= limit || script < 0 || script >= scriptCodeCount) { 66 success = LE_ILLEGAL_ARGUMENT_ERROR; 67 return NULL; 68 } 69 70 *offset = limit; 71 return this; 72} 73 74void LEFontInstance::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, 75 le_bool reverse, const LECharMapper *mapper, le_bool filterZeroWidth, LEGlyphStorage &glyphStorage) const 76{ 77 le_int32 i, out = 0, dir = 1; 78 79 if (reverse) { 80 out = count - 1; 81 dir = -1; 82 } 83 84 for (i = offset; i < offset + count; i += 1, out += dir) { 85 LEUnicode16 high = chars[i]; 86 LEUnicode32 code = high; 87 88 if (i < offset + count - 1 && high >= 0xD800 && high <= 0xDBFF) { 89 LEUnicode16 low = chars[i + 1]; 90 91 if (low >= 0xDC00 && low <= 0xDFFF) { 92 code = (high - 0xD800) * 0x400 + low - 0xDC00 + 0x10000; 93 } 94 } 95 96 glyphStorage[out] = mapCharToGlyph(code, mapper, filterZeroWidth); 97 98 if (code >= 0x10000) { 99 i += 1; 100 glyphStorage[out += dir] = 0xFFFF; 101 } 102 } 103} 104 105LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const 106{ 107 return mapCharToGlyph(ch, mapper, TRUE); 108} 109 110LEGlyphID LEFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const 111{ 112 LEUnicode32 mappedChar = mapper->mapChar(ch); 113 114 if (mappedChar == 0xFFFE || mappedChar == 0xFFFF) { 115 return 0xFFFF; 116 } 117 118 if (filterZeroWidth && (mappedChar == 0x200C || mappedChar == 0x200D)) { 119 return canDisplay(mappedChar)? 0x0001 : 0xFFFF; 120 } 121 122 return mapCharToGlyph(mappedChar); 123} 124 125le_bool LEFontInstance::canDisplay(LEUnicode32 ch) const 126{ 127 return LE_GET_GLYPH(mapCharToGlyph(ch)) != 0; 128} 129 130float LEFontInstance::xUnitsToPoints(float xUnits) const 131{ 132 return (xUnits * getXPixelsPerEm()) / (float) getUnitsPerEM(); 133} 134 135float LEFontInstance::yUnitsToPoints(float yUnits) const 136{ 137 return (yUnits * getYPixelsPerEm()) / (float) getUnitsPerEM(); 138} 139 140void LEFontInstance::unitsToPoints(LEPoint &units, LEPoint &points) const 141{ 142 points.fX = xUnitsToPoints(units.fX); 143 points.fY = yUnitsToPoints(units.fY); 144} 145 146float LEFontInstance::xPixelsToUnits(float xPixels) const 147{ 148 return (xPixels * getUnitsPerEM()) / (float) getXPixelsPerEm(); 149} 150 151float LEFontInstance::yPixelsToUnits(float yPixels) const 152{ 153 return (yPixels * getUnitsPerEM()) / (float) getYPixelsPerEm(); 154} 155 156void LEFontInstance::pixelsToUnits(LEPoint &pixels, LEPoint &units) const 157{ 158 units.fX = xPixelsToUnits(pixels.fX); 159 units.fY = yPixelsToUnits(pixels.fY); 160} 161 162void LEFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const 163{ 164 pixels.fX = xUnitsToPoints(xFunits) * getScaleFactorX(); 165 pixels.fY = yUnitsToPoints(yFunits) * getScaleFactorY(); 166} 167 168le_int32 LEFontInstance::getLineHeight() const 169{ 170 return getAscent() + getDescent() + getLeading(); 171} 172 173U_NAMESPACE_END 174 175