1 /* 2 * This file is part of the html renderer for KDE. 3 * 4 * Copyright (C) 2000-2003 Lars Knoll (knoll@kde.org) 5 * (C) 2000 Antti Koivisto (koivisto@kde.org) 6 * (C) 2000 Dirk Mueller (mueller@kde.org) 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 * 23 */ 24 25 #ifndef KHTMLFONT_H 26 #define KHTMLFONT_H 27 28 #include <khtml_global.h> 29 #include <khtml_settings.h> 30 31 #include <QCache> 32 #include <QFont> 33 #include <QFontMetrics> 34 #include <QPainter> 35 36 #include "misc/shared.h" 37 38 namespace DOM 39 { 40 class DOMString; 41 } 42 43 namespace khtml 44 { 45 class RenderStyle; 46 class CSSStyleSelector; 47 48 class CachedFontFamily; 49 50 class CachedFontInstance: public Shared<CachedFontInstance> 51 { 52 public: 53 CachedFontInstance(CachedFontFamily *parent, int size); 54 55 QFont f; 56 QFontMetrics fm; // note:stuff below is faster when applicable. 57 // Also, do not rearrange these two fields --- one neefs f to initialize fm 58 59 // We store cached width metrics as a two-level tree --- 60 // top-level is row for the codepoint, second is column. 61 // Some rows may have no information on them. 62 // For a cell, value 255 means no known width (or a width >= 255) cachedCharWidth(unsigned short codePoint)63 unsigned cachedCharWidth(unsigned short codePoint) 64 { 65 unsigned width = 0xFF; 66 if (RowInfo *row = rows[codePoint >> 8]) { 67 width = row->widths[codePoint & 0xFF]; 68 } 69 if (width != 0xFF) { 70 return width; 71 } else { 72 return calcAndCacheWidth(codePoint); 73 } 74 } 75 cachedCharWidth(const QChar & c)76 unsigned cachedCharWidth(const QChar &c) 77 { 78 return cachedCharWidth(c.unicode()); 79 } 80 81 // query again all metrics 82 void invalidate(); 83 84 // Simple cached metrics, set on creation 85 int ascent; 86 int descent; 87 int height; 88 int lineSpacing; 89 int xHeight; 90 int m_zeroCharWidth; 91 mutable bool invalidated; 92 93 ~CachedFontInstance(); 94 private: 95 unsigned calcAndCacheWidth(unsigned short codePoint); 96 97 struct RowInfo { 98 unsigned char widths[256]; 99 RowInfoRowInfo100 RowInfo() 101 { 102 for (int i = 0; i < 256; ++i) { 103 widths[i] = 0xFF; 104 } 105 } 106 }; 107 108 RowInfo *rows[256]; 109 CachedFontFamily *parent; 110 int size; // the size we were created with 111 }; 112 113 class FontDef 114 { 115 public: FontDef()116 FontDef() 117 : family(KHTMLGlobal::defaultHTMLSettings()->stdFontName()), size(0), italic(false), smallCaps(false), weight(QFont::Normal) {} 118 bool operator == (const FontDef &other) const 119 { 120 return (family == other.family && 121 size == other.size && 122 italic == other.italic && 123 smallCaps == other.smallCaps && 124 weight == other.weight); 125 } 126 127 QString family; 128 short int size; 129 bool italic : 1; 130 bool smallCaps : 1; 131 unsigned int weight : 8; 132 }; 133 134 class Font 135 { 136 friend class RenderStyle; 137 friend class CSSStyleSelector; 138 139 static CachedFontInstance *defaultCFI; 140 public: 141 static void initDefault(); 142 Font()143 Font() : fontDef(), cfi(defaultCFI), scFont(nullptr), letterSpacing(0), wordSpacing(0) {} Font(const FontDef & fd)144 Font(const FontDef &fd) 145 : fontDef(fd), cfi(defaultCFI), scFont(nullptr), letterSpacing(0), wordSpacing(0) 146 {} Font(const Font & o)147 Font(const Font &o) 148 : fontDef(o.fontDef), cfi(o.cfi), scFont(o.scFont), letterSpacing(o.letterSpacing), wordSpacing(o.wordSpacing) 149 { 150 if (o.scFont) { 151 scFont = new QFont(*o.scFont); 152 } 153 } ~Font()154 ~Font() 155 { 156 delete scFont; 157 } 158 159 bool operator == (const Font &other) const 160 { 161 return (fontDef == other.fontDef && 162 letterSpacing == other.letterSpacing && 163 wordSpacing == other.wordSpacing); 164 } 165 getFontDef()166 const FontDef &getFontDef() const 167 { 168 return fontDef; 169 } 170 171 void update(int logicalDpiY) const; 172 173 static void invalidateCachedFontFamily(const QString &familyName); 174 static void markAllCachedFontsAsValid(); 175 176 /** 177 * Draws a piece from the given piece of text. 178 * @param p painter 179 * @param x x-coordinate to begin drawing, always denotes leftmost position 180 * @param y y-coordinate of baseline of text 181 * @param str string to draw a piece from 182 * @param slen total length of string 183 * @param pos zero-based offset of beginning of piece 184 * @param len length of piece 185 * @param width additional pixels to be distributed equally among all 186 * spaces 187 * @param d text direction 188 * @param from begin with this position relative to @p pos, -1 to start 189 * at @p pos 190 * @param to stop before this position relative to @p pos, -1 to use full 191 * length of piece 192 * @param bg if valid, fill the background of the drawn piece with this 193 * color 194 * @param uy y-coordinate of top position, used for background and text 195 * decoration painting 196 * @param h total height of line, only used for background and text 197 * decoration painting 198 * @param deco combined text decoration (see Decoration) 199 */ 200 void drawText(QPainter *p, int x, int y, const QChar *str, const int slen, int pos, int len, int width, 201 Qt::LayoutDirection d, int from = -1, int to = -1, QColor bg = QColor(), 202 int uy = -1, int h = -1, int deco = 0) const; 203 204 /** returns the width of the given string chunk in pixels. 205 * 206 * The method also considers various styles like text-align and font-variant 207 * @param str pointer to string 208 * @param slen total length of string 209 * @param pos zero-based position in string where to start measuring 210 * @param len count of characters up to which the width should be determined 211 * @param fast Use simplest/fastest algorithm (for e.g strings without special/combining chars) 212 * @param start starting position of inline text box within str, only 213 * used when toAdd is specified. 214 * @param end ending position of inline text box within str, only 215 * used when toAdd is specified. 216 * @param toAdd amount of pixels to distribute evenly among all spaces of 217 * str. Note that toAdd applies to all spaces within str, but only those 218 * within [pos, pos+len) are counted towards the width. 219 */ 220 int width(const QChar *str, int slen, int pos, int len, bool fast, int start = 0, int end = 0, int toAdd = 0) const; 221 /** return the width of the given char in pixels. 222 * 223 * The method also considers various styles like text-align and font-variant 224 * @param str pointer to string 225 * @param slen total length of string 226 * @param pos zero-based position of char in string 227 */ 228 int charWidth(const QChar *str, int slen, int pos, bool fast) const; 229 230 /** Text decoration constants. 231 * 232 * The enumeration constant values match those of ETextDecoration, but only 233 * a subset is supported. 234 */ 235 enum Decoration { UNDERLINE = 0x1, OVERLINE = 0x2, LINE_THROUGH = 0x4 }; 236 // Keep in sync with ETextDecoration 237 238 /** draws text decoration 239 * @param p painter 240 * @param x x-coordinate 241 * @param y top y-coordinate of line box 242 * @param baseline baseline 243 * @param width length of decoration in pixels 244 * @param height height of line box 245 * @param deco decoration to be drawn (see Decoration). The enumeration 246 * constants may be combined. 247 */ 248 void drawDecoration(QPainter *p, int x, int y, int baseline, int width, int height, int deco) const; 249 250 /** returns letter spacing 251 */ getLetterSpacing()252 int getLetterSpacing() const 253 { 254 return letterSpacing; 255 } 256 /** returns word spacing 257 */ getWordSpacing()258 int getWordSpacing() const 259 { 260 return wordSpacing; 261 } 262 263 // for SVG ascent()264 int ascent() const 265 { 266 return cfi->ascent; 267 } descent()268 int descent() const 269 { 270 return cfi->descent; 271 } height()272 int height() const 273 { 274 return cfi->height; 275 } lineSpacing()276 int lineSpacing() const 277 { 278 return cfi->lineSpacing; 279 } xHeight()280 int xHeight() const 281 { 282 return cfi->xHeight; 283 } 284 285 // return -1 if '0' char glyph not in font zeroCharWidth()286 int zeroCharWidth() const 287 { 288 return cfi->m_zeroCharWidth; 289 } 290 //FIXME: IMPLEMENT ME unitsPerEm()291 unsigned unitsPerEm() const 292 { 293 return 0; 294 } spaceWidth()295 int spaceWidth() const 296 { 297 return 0; 298 } tabWidth()299 int tabWidth() const 300 { 301 return 8 * spaceWidth(); 302 } 303 isInvalidated()304 bool isInvalidated() const 305 { 306 return cfi->invalidated; 307 } validate()308 void validate() const 309 { 310 cfi->invalidated = false; 311 } 312 313 // SVG helper function 314 float floatWidth(QChar *str, int pos, int len, int extraCharsAvailable, int &charsConsumed, DOM::DOMString &glyphName) const; 315 316 float floatWidth(QChar *str, int pos, int len) const; 317 318 private: 319 static CachedFontFamily *queryFamily(const QString &name, int weight, bool italic); 320 321 mutable FontDef fontDef; 322 mutable WTF::SharedPtr<CachedFontInstance> cfi; 323 mutable QFont *scFont; 324 short letterSpacing; 325 short wordSpacing; 326 }; 327 328 } // namespace 329 330 #endif 331