| 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 |