LEFontInstance.cpp revision c73f511526464f8e56c242df80552e9b0d94ae3d
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