~ubuntu-branches/ubuntu/trusty/harfbuzz/trusty

« back to all changes in this revision

Viewing changes to src/hb-old/harfbuzz-hebrew.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2013-12-09 11:03:19 UTC
  • mfrom: (2.1.16 trusty-proposed)
  • Revision ID: package-import@ubuntu.com-20131209110319-rsy56xzp01r9wqzx
Tags: 0.9.24-2ubuntu1
* Merge with Debian, remaining changes
  - Build using dh-autoreconf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
3
 
 *
4
 
 * This is part of HarfBuzz, an OpenType Layout engine library.
5
 
 *
6
 
 * Permission is hereby granted, without written agreement and without
7
 
 * license or royalty fees, to use, copy, modify, and distribute this
8
 
 * software and its documentation for any purpose, provided that the
9
 
 * above copyright notice and the following two paragraphs appear in
10
 
 * all copies of this software.
11
 
 *
12
 
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 
 * DAMAGE.
17
 
 *
18
 
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 
 */
24
 
 
25
 
#include "harfbuzz-shaper.h"
26
 
#include "harfbuzz-shaper-private.h"
27
 
#include <assert.h>
28
 
 
29
 
/*
30
 
// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
31
 
// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
32
 
*/
33
 
#ifndef NO_OPENTYPE
34
 
static const HB_OpenTypeFeature hebrew_features[] = {
35
 
    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
36
 
    {0, 0}
37
 
};
38
 
#endif
39
 
 
40
 
/* Hebrew shaping. In the non opentype case we try to use the
41
 
   presentation forms specified for Hebrew. Especially for the
42
 
   ligatures with Dagesh this gives much better results than we could
43
 
   achieve manually.
44
 
*/
45
 
HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
46
 
{
47
 
    enum {
48
 
        Dagesh = 0x5bc,
49
 
        ShinDot = 0x5c1,
50
 
        SinDot = 0x5c2,
51
 
        Patah = 0x5b7,
52
 
        Qamats = 0x5b8,
53
 
        Holam = 0x5b9,
54
 
        Rafe = 0x5bf
55
 
    };
56
 
 
57
 
    assert(shaper_item->item.script == HB_Script_Hebrew);
58
 
 
59
 
#ifndef NO_OPENTYPE
60
 
    if (HB_SelectScript(shaper_item, hebrew_features)) {
61
 
 
62
 
        const int availableGlyphs = shaper_item->num_glyphs;
63
 
        if (!HB_ConvertStringToGlyphIndices(shaper_item))
64
 
            return FALSE;
65
 
 
66
 
        HB_HeuristicSetGlyphAttributes(shaper_item);
67
 
        HB_OpenTypeShape(shaper_item, /*properties*/0);
68
 
        return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
69
 
    }
70
 
#endif
71
 
 
72
 
    {
73
 
        const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
74
 
        unsigned short *logClusters = shaper_item->log_clusters;
75
 
        HB_GlyphAttributes *attributes = shaper_item->attributes;
76
 
 
77
 
        HB_Bool haveGlyphs;
78
 
        int slen = 1;
79
 
        int cluster_start = 0;
80
 
        hb_uint32 i;
81
 
 
82
 
        HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
83
 
        *shapedChars = *uc;
84
 
        logClusters[0] = 0;
85
 
 
86
 
        for (i = 1; i < shaper_item->item.length; ++i) {
87
 
            hb_uint16 base = shapedChars[cluster_start];
88
 
            hb_uint16 shaped = 0;
89
 
            HB_Bool invalid = FALSE;
90
 
            if (uc[i] == Dagesh) {
91
 
                if (base >= 0x5d0
92
 
                    && base <= 0x5ea
93
 
                    && base != 0x5d7
94
 
                    && base != 0x5dd
95
 
                    && base != 0x5df
96
 
                    && base != 0x5e2
97
 
                    && base != 0x5e5) {
98
 
                    shaped = base - 0x5d0 + 0xfb30;
99
 
                } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
100
 
                    shaped = base + 2;
101
 
                } else {
102
 
                    invalid = TRUE;
103
 
                }
104
 
            } else if (uc[i] == ShinDot) {
105
 
                if (base == 0x05e9)
106
 
                    shaped = 0xfb2a;
107
 
                else if (base == 0xfb49)
108
 
                    shaped = 0xfb2c;
109
 
                else
110
 
                    invalid = TRUE;
111
 
            } else if (uc[i] == SinDot) {
112
 
                if (base == 0x05e9)
113
 
                    shaped = 0xfb2b;
114
 
                else if (base == 0xfb49)
115
 
                    shaped = 0xfb2d;
116
 
                else
117
 
                    invalid = TRUE;
118
 
            } else if (uc[i] == Patah) {
119
 
                if (base == 0x5d0)
120
 
                    shaped = 0xfb2e;
121
 
            } else if (uc[i] == Qamats) {
122
 
                if (base == 0x5d0)
123
 
                    shaped = 0xfb2f;
124
 
            } else if (uc[i] == Holam) {
125
 
                if (base == 0x5d5)
126
 
                    shaped = 0xfb4b;
127
 
            } else if (uc[i] == Rafe) {
128
 
                if (base == 0x5d1)
129
 
                    shaped = 0xfb4c;
130
 
                else if (base == 0x5db)
131
 
                    shaped = 0xfb4d;
132
 
                else if (base == 0x5e4)
133
 
                    shaped = 0xfb4e;
134
 
            }
135
 
 
136
 
            if (invalid) {
137
 
                shapedChars[slen] = 0x25cc;
138
 
                attributes[slen].clusterStart = TRUE;
139
 
                attributes[slen].mark = FALSE;
140
 
                attributes[slen].combiningClass = 0;
141
 
                cluster_start = slen;
142
 
                ++slen;
143
 
            }
144
 
            if (shaped) {
145
 
                if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
146
 
                    shapedChars[cluster_start] = shaped;
147
 
                } else
148
 
                    shaped = 0;
149
 
            }
150
 
            if (!shaped) {
151
 
                HB_CharCategory category;
152
 
                int cmb;
153
 
                shapedChars[slen] = uc[i];
154
 
                HB_GetUnicodeCharProperties(shaper_item->ufuncs, uc[i], &category, &cmb);
155
 
                if (category != HB_Mark_NonSpacing) {
156
 
                    attributes[slen].clusterStart = TRUE;
157
 
                    attributes[slen].mark = FALSE;
158
 
                    attributes[slen].combiningClass = 0;
159
 
                    attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
160
 
                    cluster_start = slen;
161
 
                } else {
162
 
                    attributes[slen].clusterStart = FALSE;
163
 
                    attributes[slen].mark = TRUE;
164
 
                    attributes[slen].combiningClass = cmb;
165
 
                }
166
 
                ++slen;
167
 
            }
168
 
            logClusters[i] = cluster_start;
169
 
        }
170
 
 
171
 
        haveGlyphs = shaper_item->font->klass
172
 
            ->convertStringToGlyphIndices(shaper_item->font,
173
 
                                          shapedChars, slen,
174
 
                                          shaper_item->glyphs, &shaper_item->num_glyphs,
175
 
                                          shaper_item->item.bidiLevel % 2);
176
 
 
177
 
        HB_FREE_STACKARRAY(shapedChars);
178
 
 
179
 
        if (!haveGlyphs)
180
 
            return FALSE;
181
 
 
182
 
        HB_HeuristicPosition(shaper_item);
183
 
    }
184
 
 
185
 
    return TRUE;
186
 
}
187