MinikinSkia.cpp revision 531dab6d3a2ffcd13684367659dfd0296f86cfe5
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <SkTypeface.h> 18#include <SkPaint.h> 19 20#define LOG_TAG "Minikin" 21#include <cutils/log.h> 22 23#include "MinikinSkia.h" 24 25namespace android { 26 27MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) : 28 mTypeface(typeface) { 29} 30 31MinikinFontSkia::~MinikinFontSkia() { 32 SkSafeUnref(mTypeface); 33} 34 35bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const { 36 SkPaint paint; 37 paint.setTypeface(mTypeface); 38 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); 39 uint16_t glyph16; 40 paint.textToGlyphs(&codepoint, sizeof(codepoint), &glyph16); 41 *glyph = glyph16; 42 return !!glyph16; 43} 44 45static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) { 46 skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); 47 skPaint->setTextSize(paint.size); 48 skPaint->setTextScaleX(paint.scaleX); 49 skPaint->setTextSkewX(paint.skewX); 50 MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags); 51 // Apply font fakery on top of user-supplied flags. 52 MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery); 53} 54 55float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id, 56 const MinikinPaint &paint) const { 57 SkPaint skPaint; 58 uint16_t glyph16 = glyph_id; 59 SkScalar skWidth; 60 MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint); 61 skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL); 62#ifdef VERBOSE 63 ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth); 64#endif 65 return skWidth; 66} 67 68void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id, 69 const MinikinPaint& paint) const { 70 SkPaint skPaint; 71 uint16_t glyph16 = glyph_id; 72 SkRect skBounds; 73 MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint); 74 skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds); 75 bounds->mLeft = skBounds.fLeft; 76 bounds->mTop = skBounds.fTop; 77 bounds->mRight = skBounds.fRight; 78 bounds->mBottom = skBounds.fBottom; 79} 80 81bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) { 82 if (buf == NULL) { 83 const size_t tableSize = mTypeface->getTableSize(tag); 84 *size = tableSize; 85 return tableSize != 0; 86 } else { 87 const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf); 88 *size = actualSize; 89 return actualSize != 0; 90 } 91} 92 93SkTypeface *MinikinFontSkia::GetSkTypeface() const { 94 return mTypeface; 95} 96 97int32_t MinikinFontSkia::GetUniqueId() const { 98 return mTypeface->uniqueID(); 99} 100 101uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) { 102 uint32_t flags = paint->getFlags(); 103 SkPaint::Hinting hinting = paint->getHinting(); 104 // select only flags that might affect text layout 105 flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag | 106 SkPaint::kSubpixelText_Flag | SkPaint::kDevKernText_Flag | 107 SkPaint::kEmbeddedBitmapText_Flag | SkPaint::kAutoHinting_Flag | 108 SkPaint::kVerticalText_Flag); 109 flags |= (hinting << 16); 110 return flags; 111} 112 113void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) { 114 paint->setFlags(paintFlags & SkPaint::kAllFlags); 115 paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16)); 116} 117 118void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) { 119 paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface()); 120 paint->setFakeBoldText(paint->isFakeBoldText() || fakery.isFakeBold()); 121 if (fakery.isFakeItalic()) { 122 paint->setTextSkewX(paint->getTextSkewX() - 0.25f); 123 } 124} 125 126} 127