Path: blob/master/thirdparty/graphite/src/inc/GlyphCache.h
9906 views
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later1// Copyright 2012, SIL International, All rights reserved.23#pragma once456#include "graphite2/Font.h"7#include "inc/Main.h"8#include "inc/Position.h"9#include "inc/GlyphFace.h"1011namespace graphite2 {1213class Face;14class FeatureVal;15class Segment;161718struct SlantBox19{20static const SlantBox empty;2122// SlantBox(float psi = 0., float pdi = 0., float psa = 0., float pda = 0.) : si(psi), di(pdi), sa(psa), da(pda) {};23float width() const { return sa - si; }24float height() const { return da - di; }25float si; // min26float di; // min27float sa; // max28float da; // max29};303132struct BBox33{34BBox(float pxi = 0, float pyi = 0., float pxa = 0., float pya = 0.) : xi(pxi), yi(pyi), xa(pxa), ya(pya) {};35float width() const { return xa - xi; }36float height() const { return ya - yi; }37float xi; // min38float yi; // min39float xa; // max40float ya; // max41};424344class GlyphBox45{46GlyphBox(const GlyphBox &);47GlyphBox & operator = (const GlyphBox &);4849public:50GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {};5152void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; }53Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; }54const Rect &slant() const { return _slant; }55uint8 num() const { return _num; }56const Rect *subs() const { return _subs; }5758private:59uint8 _num;60unsigned short _bitmap;61Rect _slant;62Rect _subs[1];63};6465class GlyphCache66{67class Loader;6869GlyphCache(const GlyphCache&);70GlyphCache& operator=(const GlyphCache&);7172public:73GlyphCache(const Face & face, const uint32 face_options);74~GlyphCache();7576unsigned short numGlyphs() const throw();77unsigned short numAttrs() const throw();78unsigned short unitsPerEm() const throw();7980const GlyphFace *glyph(unsigned short glyphid) const; //result may be changed by subsequent call with a different glyphid81const GlyphFace *glyphSafe(unsigned short glyphid) const;82float getBoundingMetric(unsigned short glyphid, uint8 metric) const;83uint8 numSubBounds(unsigned short glyphid) const;84float getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const;85const Rect & slant(unsigned short glyphid) const { return _boxes[glyphid] ? _boxes[glyphid]->slant() : _empty_slant_box; }86const SlantBox & getBoundingSlantBox(unsigned short glyphid) const;87const BBox & getBoundingBBox(unsigned short glyphid) const;88const SlantBox & getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const;89const BBox & getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const;90bool check(unsigned short glyphid) const;91bool hasBoxes() const { return _boxes != 0; }9293CLASS_NEW_DELETE;9495private:96const Rect _empty_slant_box;97const Loader * _glyph_loader;98const GlyphFace * * _glyphs;99GlyphBox * * _boxes;100unsigned short _num_glyphs,101_num_attrs,102_upem;103};104105inline106unsigned short GlyphCache::numGlyphs() const throw()107{108return _num_glyphs;109}110111inline112unsigned short GlyphCache::numAttrs() const throw()113{114return _num_attrs;115}116117inline118unsigned short GlyphCache::unitsPerEm() const throw()119{120return _upem;121}122123inline124bool GlyphCache::check(unsigned short glyphid) const125{126return _boxes && glyphid < _num_glyphs;127}128129inline130const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const131{132return glyphid < _num_glyphs ? glyph(glyphid) : NULL;133}134135inline136float GlyphCache::getBoundingMetric(unsigned short glyphid, uint8 metric) const137{138if (glyphid >= _num_glyphs) return 0.;139switch (metric) {140case 0: return (float)(glyph(glyphid)->theBBox().bl.x); // x_min141case 1: return (float)(glyph(glyphid)->theBBox().bl.y); // y_min142case 2: return (float)(glyph(glyphid)->theBBox().tr.x); // x_max143case 3: return (float)(glyph(glyphid)->theBBox().tr.y); // y_max144case 4: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.x : 0.f); // sum_min145case 5: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.y : 0.f); // diff_min146case 6: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.x : 0.f); // sum_max147case 7: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.y : 0.f); // diff_max148default: return 0.;149}150}151152inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const153{154return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : SlantBox::empty;155}156157inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const158{159return *(BBox *)(&(glyph(glyphid)->theBBox()));160}161162inline163float GlyphCache::getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const164{165GlyphBox *b = _boxes[glyphid];166if (b == NULL || subindex >= b->num()) return 0;167168switch (metric) {169case 0: return b->subVal(subindex, 0).bl.x;170case 1: return b->subVal(subindex, 0).bl.y;171case 2: return b->subVal(subindex, 0).tr.x;172case 3: return b->subVal(subindex, 0).tr.y;173case 4: return b->subVal(subindex, 1).bl.x;174case 5: return b->subVal(subindex, 1).bl.y;175case 6: return b->subVal(subindex, 1).tr.x;176case 7: return b->subVal(subindex, 1).tr.y;177default: return 0.;178}179}180181inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const182{183GlyphBox *b = _boxes[glyphid];184return *(SlantBox *)(b->subs() + 2 * subindex + 1);185}186187inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const188{189GlyphBox *b = _boxes[glyphid];190return *(BBox *)(b->subs() + 2 * subindex);191}192193inline194uint8 GlyphCache::numSubBounds(unsigned short glyphid) const195{196return _boxes[glyphid] ? _boxes[glyphid]->num() : 0;197}198199} // namespace graphite2200201202