Split mixed font GlyphPage functionality to separate class
[WebKit-https.git] / Source / WebCore / platform / graphics / mac / GlyphPageMac.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "GlyphPage.h"
31
32 #include "CoreGraphicsSPI.h"
33 #include "CoreTextSPI.h"
34 #include "Font.h"
35 #include "FontCascade.h"
36 #include "WebCoreSystemInterface.h"
37 #if !PLATFORM(IOS)
38 #include <ApplicationServices/ApplicationServices.h>
39 #endif
40
41 namespace WebCore {
42
43 static bool shouldUseCoreText(const UChar* buffer, unsigned bufferLength, const Font* fontData)
44 {
45     // This needs to be kept in sync with GlyphPage::fill(). Currently, the CoreText paths are not able to handle
46     // every situtation. Returning true from this function in a new situation will require you to explicitly add
47     // handling for that situation in the CoreText paths of GlyphPage::fill().
48     if (fontData->isSystemFont())
49         return true;
50     if (fontData->platformData().isForTextCombine() || fontData->hasVerticalGlyphs()) {
51         // Ideographs don't have a vertical variant or width variants.
52         for (unsigned i = 0; i < bufferLength; ++i) {
53             if (!FontCascade::isCJKIdeograph(buffer[i]))
54                 return true;
55         }
56     }
57
58     return false;
59 }
60
61 bool GlyphPage::fill(UChar* buffer, unsigned bufferLength, const Font* fontData)
62 {
63     ASSERT(fontData == &font());
64     ASSERT(bufferLength == GlyphPage::size || bufferLength == 2 * GlyphPage::size);
65
66     Vector<CGGlyph, 512> glyphs(bufferLength);
67     unsigned glyphStep;
68     if (!shouldUseCoreText(buffer, bufferLength, fontData)) {
69         // We pass in either 256 or 512 UTF-16 characters: 256 for U+FFFF and less, 512 (double character surrogates)
70         // for U+10000 and above. It is indeed possible to get back 512 glyphs back from the API, so the glyph buffer
71         // we pass in must be 512. If we get back more than 256 glyphs though we'll ignore all the ones after 256,
72         // this should not happen as the only time we pass in 512 characters is when they are surrogates.
73         CGFontGetGlyphsForUnichars(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength);
74         glyphStep = 1;
75     } else {
76         // Because we know the implementation of shouldUseCoreText(), if the font isn't for text combine and it isn't a system font,
77         // we know it must have vertical glyphs.
78         if (fontData->platformData().isForTextCombine() || fontData->isSystemFont())
79             CTFontGetGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength);
80         else
81             CTFontGetVerticalGlyphsForCharacters(fontData->platformData().ctFont(), buffer, glyphs.data(), bufferLength);
82
83         // When buffer consists of surrogate pairs, CTFontGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters
84         // place the glyphs at indices corresponding to the first character of each pair.
85         glyphStep = bufferLength / GlyphPage::size;
86     }
87
88     bool haveGlyphs = false;
89     for (unsigned i = 0; i < GlyphPage::size; ++i) {
90         if (glyphs[i * glyphStep]) {
91             setGlyphForIndex(i, glyphs[i * glyphStep]);
92             haveGlyphs = true;
93         }
94     }
95     return haveGlyphs;
96 }
97
98 } // namespace WebCore