| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2012 Google 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 are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "core/platform/graphics/harfbuzz/HarfBuzzFace.h" | |
| 33 | |
| 34 #include "core/platform/graphics/FontPlatformData.h" | |
| 35 #include "hb-ot.h" | |
| 36 #include "hb.h" | |
| 37 | |
| 38 namespace WebCore { | |
| 39 | |
| 40 const hb_tag_t HarfBuzzFace::vertTag = HB_TAG('v', 'e', 'r', 't'); | |
| 41 const hb_tag_t HarfBuzzFace::vrt2Tag = HB_TAG('v', 'r', 't', '2'); | |
| 42 | |
| 43 // Though we have FontCache class, which provides the cache mechanism for | |
| 44 // WebKit's font objects, we also need additional caching layer for HarfBuzz | |
| 45 // to reduce the memory consumption because hb_face_t should be associated with | |
| 46 // underling font data (e.g. CTFontRef, FTFace). | |
| 47 | |
| 48 class FaceCacheEntry : public RefCounted<FaceCacheEntry> { | |
| 49 public: | |
| 50 static PassRefPtr<FaceCacheEntry> create(hb_face_t* face) | |
| 51 { | |
| 52 ASSERT(face); | |
| 53 return adoptRef(new FaceCacheEntry(face)); | |
| 54 } | |
| 55 ~FaceCacheEntry() | |
| 56 { | |
| 57 hb_face_destroy(m_face); | |
| 58 } | |
| 59 | |
| 60 hb_face_t* face() { return m_face; } | |
| 61 HashMap<uint32_t, uint16_t>* glyphCache() { return &m_glyphCache; } | |
| 62 | |
| 63 private: | |
| 64 explicit FaceCacheEntry(hb_face_t* face) | |
| 65 : m_face(face) | |
| 66 { } | |
| 67 | |
| 68 hb_face_t* m_face; | |
| 69 HashMap<uint32_t, uint16_t> m_glyphCache; | |
| 70 }; | |
| 71 | |
| 72 typedef HashMap<uint64_t, RefPtr<FaceCacheEntry>, WTF::IntHash<uint64_t>, WTF::U
nsignedWithZeroKeyHashTraits<uint64_t> > HarfBuzzFaceCache; | |
| 73 | |
| 74 static HarfBuzzFaceCache* harfBuzzFaceCache() | |
| 75 { | |
| 76 DEFINE_STATIC_LOCAL(HarfBuzzFaceCache, s_harfBuzzFaceCache, ()); | |
| 77 return &s_harfBuzzFaceCache; | |
| 78 } | |
| 79 | |
| 80 HarfBuzzFace::HarfBuzzFace(FontPlatformData* platformData, uint64_t uniqueID) | |
| 81 : m_platformData(platformData) | |
| 82 , m_uniqueID(uniqueID) | |
| 83 , m_scriptForVerticalText(HB_SCRIPT_INVALID) | |
| 84 { | |
| 85 HarfBuzzFaceCache::AddResult result = harfBuzzFaceCache()->add(m_uniqueID, 0
); | |
| 86 if (result.isNewEntry) | |
| 87 result.iterator->value = FaceCacheEntry::create(createFace()); | |
| 88 result.iterator->value->ref(); | |
| 89 m_face = result.iterator->value->face(); | |
| 90 m_glyphCacheForFaceCacheEntry = result.iterator->value->glyphCache(); | |
| 91 } | |
| 92 | |
| 93 HarfBuzzFace::~HarfBuzzFace() | |
| 94 { | |
| 95 HarfBuzzFaceCache::iterator result = harfBuzzFaceCache()->find(m_uniqueID); | |
| 96 ASSERT_WITH_SECURITY_IMPLICATION(result != harfBuzzFaceCache()->end()); | |
| 97 ASSERT(result.get()->value->refCount() > 1); | |
| 98 result.get()->value->deref(); | |
| 99 if (result.get()->value->refCount() == 1) | |
| 100 harfBuzzFaceCache()->remove(m_uniqueID); | |
| 101 } | |
| 102 | |
| 103 static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face) | |
| 104 { | |
| 105 static const unsigned maxCount = 32; | |
| 106 | |
| 107 unsigned scriptCount = maxCount; | |
| 108 hb_tag_t scriptTags[maxCount]; | |
| 109 hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, sc
riptTags); | |
| 110 for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) { | |
| 111 unsigned languageCount = maxCount; | |
| 112 hb_tag_t languageTags[maxCount]; | |
| 113 hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex,
0, &languageCount, languageTags); | |
| 114 for (unsigned languageIndex = 0; languageIndex < languageCount; ++langua
geIndex) { | |
| 115 unsigned featureIndex; | |
| 116 if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptI
ndex, languageIndex, HarfBuzzFace::vertTag, &featureIndex) | |
| 117 || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scri
ptIndex, languageIndex, HarfBuzzFace::vrt2Tag, &featureIndex)) | |
| 118 return hb_ot_tag_to_script(scriptTags[scriptIndex]); | |
| 119 } | |
| 120 } | |
| 121 return HB_SCRIPT_INVALID; | |
| 122 } | |
| 123 | |
| 124 void HarfBuzzFace::setScriptForVerticalGlyphSubstitution(hb_buffer_t* buffer) | |
| 125 { | |
| 126 if (m_scriptForVerticalText == HB_SCRIPT_INVALID) | |
| 127 m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_face)
; | |
| 128 hb_buffer_set_script(buffer, m_scriptForVerticalText); | |
| 129 } | |
| 130 | |
| 131 } // namespace WebCore | |
| OLD | NEW |