MinikinUtils.cpp revision 805f6ebf17e2791624bb1a30834b4c1cc65583bf
1/* 2 * Copyright (C) 2014 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#define LOG_TAG "Minikin" 18#include <cutils/log.h> 19#include <string> 20 21#include "SkPathMeasure.h" 22#include "Paint.h" 23#include "TypefaceImpl.h" 24 25#include "MinikinUtils.h" 26 27namespace android { 28 29// Do an sprintf starting at offset n, abort on overflow 30static int snprintfcat(char* buf, int off, int size, const char* format, ...) 31 __attribute__((__format__(__printf__, 4, 5))); 32static int snprintfcat(char* buf, int off, int size, const char* format, ...) { 33 va_list args; 34 va_start(args, format); 35 int n = vsnprintf(buf + off, size - off, format, args); 36 LOG_ALWAYS_FATAL_IF(n >= size - off, "String overflow in setting layout properties"); 37 va_end(args); 38 return off + n; 39} 40 41void MinikinUtils::doLayout(Layout* layout, const Paint* paint, int bidiFlags, TypefaceImpl* typeface, 42 const uint16_t* buf, size_t start, size_t count, size_t bufSize) { 43 TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface); 44 layout->setFontCollection(resolvedFace->fFontCollection); 45 FontStyle resolved = resolvedFace->fStyle; 46 47 /* Prepare minikin FontStyle */ 48 SkString langStr = paint->getPaintOptionsAndroid().getLanguage().getTag(); 49 FontLanguage minikinLang(langStr.c_str(), langStr.size()); 50 SkPaintOptionsAndroid::FontVariant var = paint->getPaintOptionsAndroid().getFontVariant(); 51 FontVariant minikinVariant = var == SkPaintOptionsAndroid::kElegant_Variant ? VARIANT_ELEGANT 52 : VARIANT_COMPACT; 53 FontStyle minikinStyle(minikinLang, minikinVariant, resolved.getWeight(), resolved.getItalic()); 54 55 /* Prepare minikin Paint */ 56 MinikinPaint minikinPaint; 57 minikinPaint.size = (int)/*WHY?!*/paint->getTextSize(); 58 minikinPaint.scaleX = paint->getTextScaleX(); 59 minikinPaint.skewX = paint->getTextSkewX(); 60 minikinPaint.letterSpacing = paint->getLetterSpacing(); 61 minikinPaint.paintFlags = MinikinFontSkia::packPaintFlags(paint); 62 minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings(); 63 64 layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint); 65} 66 67float MinikinUtils::xOffsetForTextAlign(Paint* paint, const Layout& layout) { 68 switch (paint->getTextAlign()) { 69 case Paint::kCenter_Align: 70 return layout.getAdvance() * -0.5f; 71 break; 72 case Paint::kRight_Align: 73 return -layout.getAdvance(); 74 break; 75 default: 76 break; 77 } 78 return 0; 79} 80 81float MinikinUtils::hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path) { 82 float align = 0; 83 switch (paint->getTextAlign()) { 84 case Paint::kCenter_Align: 85 align = -0.5f; 86 break; 87 case Paint::kRight_Align: 88 align = -1; 89 break; 90 default: 91 return 0; 92 } 93 SkPathMeasure measure(path, false); 94 return align * (layout.getAdvance() - measure.getLength()); 95} 96 97} 98