📄 glyph_buffer.h
字号:
/* $Id: glyph_buffer.h,v 1.27 2004/01/02 15:42:43 mbn Exp $
**
** ClanLib Game SDK
** Copyright (C) 2003 The ClanLib Team
** For a total list of contributers see the file CREDITS.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**
*/
//! clanDisplay="Fonts"
//! header=display.h
#ifndef header_glyph_buffer
#define header_glyph_buffer
#if _MSC_VER > 1000
#pragma once
#endif
#ifdef _MSC_VER
#pragma warning( disable : 4786)
#endif
#include <map>
#include <vector>
#include <utility>
#include "font.h"
#include "../Core/Math/origin.h"
#include "color.h"
class CL_Point;
class CL_Rect;
class CL_GraphicContext;
//: Stores and draws glyphs in one or more fonts.
//- !group=Display/Fonts!
//- !header=display.h!
//- <p>CL_GlyphBuffer is mostly useful for text effects, for concatenating
//- multiple CL_Font or CL_TextStyler draw_to_gb()s, or for
//- when you need access to the low-level glyph positioning data. You can
//- also use it to save time by only rendering a bit of text once when you need
//- to, for example, both draw that text and know its bounding rectangle. But
//- for optimiziation purposes alone when dealing with unchanging text, you
//- should instead
//- have CL_Font or CL_TextStyler render onto a CL_Canvas or CL_Surface.</p>
//- <p>A glyph buffer consists of a series of characters and positions,
//- and markers for font changes and various other text-altering infomration. The internal data structures used
//- are made accessible and mutable externally. CL_Font
//- and CL_TextStyler both have draw_to_gb() methods, which allows them to
//- put data into a CL_GlyphBuffer rather than drawing to a CL_GraphicContext. </p>
//- <p>The effect maps for color, angle, and scale allow you to affect those properties
//- for individual glyphs during drawing and bounding rect calculation. The angle and scale maps are different
//- from the GlyphBuffer angle and scale properties; the properties apply to the entire CL_GlyphBuffer as a whole, while entries
//- in the effect maps affect individual glyphs seperately. It's not legal to insert
//- an effect map entry for a glyph that doesn't exist.</p>
//- <p>Unlike scale effects map entries, which are multiplied by the CL_Font's existing scale,
//- color effect map entries entirely override the CL_Font's color. No blending between
//- the two colors is performed. Also, it's your responsibility to make sure that CL_Fonts have the right
//- blending functions.</p>
//- <p>In functions that calculate the size or bounding rectangle of the GlyphBuffer
//- (such as bouding_rect(), get_size(), and the alignment calculations within draw),
//- effect properties do take effect on the final rectangle, but GlyphBuffer rotation
//- and scaling (set with CL_GlyphBuffer::set_angle(), and CL_GlyphBuffer::set_scale(),
//- respectively) do not. This is consistent with the behavior of CL_Sprite and CL_Surface; the content
//- affects bounding rect calculation, but the other properties of the object
//- do not.</p>
class CL_GlyphBuffer
{
//! Construction:
public:
//: Constructs a glyph buffer.
CL_GlyphBuffer();
virtual ~CL_GlyphBuffer() {;}
//! Subclasses:
public:
//: A character and position describing a glyph in the buffer, stored in the glyphs vector.
struct Glyph
{
//:Constructs a new Glyph
//p: The CL_Point that will be assigned to pos
//c: The unsigned char that will be assigned to character
Glyph() {;}
Glyph(CL_Point p, unsigned char c) : pos(p), character(c) {;}
//: The position where the glyph is drawn.
CL_Point pos;
//: The character which determines the glyph that's drawn.
unsigned char character;
};
//: Represents a subsection of the buffer
struct Range
{
//:Constructs a new Range.
//new_start: The starting index of the range, inclusive
//new_end: The ending index of the range, exclusive
//gb: Constructs a new Range that encompasses this entire CL_GlyphBuffer
Range() : start(0), end(0) {;}
Range(const CL_GlyphBuffer& gb) : start(0), end(int(gb.get_glyphs().size())) {;}
Range(int new_start, int new_end) : start(new_start), end(new_end) {;}
//: Makes range valid for a given GlyphBuffer.
//- <p> This is automatically called when you pass the range to any GlyphBuffer method.</p>
void verify(const CL_GlyphBuffer& gb);
//: Pulls in the range at the beginning until it reaches a drawable glyph
void remove_invis_left(const CL_GlyphBuffer& gb);
//: Pulls in the range at the end until it reaches a drawable glyph
void remove_invis_right(const CL_GlyphBuffer& gb);
//: Pulls in the range at both sides until it reaches a drawable glyph
void remove_invis_both(const CL_GlyphBuffer& gb)
{remove_invis_left(gb); remove_invis_right(gb);}
//The starting index of the range, inclusive.
int start;
//The ending index of the range, exclusive.
int end;
};
//! Attributes:
public:
//: Returns a reference to the glyphs in the buffer and their drawing positions.
//- <p>See CL_GlyphBuffer::Glyph for details./p>
std::vector<Glyph>& get_glyphs() {return glyphs;}
const std::vector<Glyph>& get_glyphs() const {return glyphs;}
//: Returns a reference to the font map.
//- <p>Elements of the glyphs vector before the first font marker are ignored. Each element
//- within this map causes a change in the font while drawing, where the key of the
//- element is the index in the glyphs vector before which the font is changed.</p>
std::map<int, CL_Font>& get_font_markers() {return font_markers;}
const std::map<int, CL_Font>& get_font_markers() const {return font_markers;}
//: Returns a reference to the color effect map.
std::map<int, CL_Color>& get_color_effects() {return color_effects;}
const std::map<int, CL_Color>& get_color_effects() const {return color_effects;}
//: Returns a reference to the x scale effect map.
//- <p> Scaling occurs away from the upper-left corner of each glyph. </p>
std::map<int, float>& get_scale_x_effects() {return scale_x_effects;}
const std::map<int, float>& get_scale_x_effects() const {return scale_x_effects;}
//: Returns a reference to the y scale effect map.
//- <p> Scaling occurs away from the upper-left corner of each glyph. </p>
std::map<int, float>& get_scale_y_effects() {return scale_y_effects;}
const std::map<int, float>& get_scale_y_effects() const {return scale_y_effects;}
//: Returns a reference to the character angle effect map.
std::map<int, float>& get_angle_effects() {return angle_effects;}
const std::map<int, float>& get_angle_effects() const {return angle_effects;}
//: Returns an iterator to the font_marker associated with a particular glyph.
//- <p> If a negative index is supplied, assumes glyph 0. If an index
//- past the last element is supplied, assumes the last element. If
//- there are no CL_Fonts in the GlyphBuffer, or if there is no CL_Font
//- associated with that glyph, returns the end iterator.</p>
std::map<int, CL_Font>::iterator get_font_for(int glyph_index);
std::map<int, CL_Font>::const_iterator get_font_for(int glyph_index) const;
//: Returns the width of the entire buffer, or a sub-Range.
//return: The width in pixels.
//param range: A subsection of the glyphs vector to get the width of.
//param idx: The vector index of a single glyph to get the width of.
//param ignore_invis: If true, ignores invisible glyphs (glyphs without an actual visual glyph in the font)
int get_width(bool ignore_invis = true) const
{return get_width(Range(*this), ignore_invis);}
int get_width(int idx, bool ignore_invis = true) const
{return get_width(Range(idx, idx+1), ignore_invis);}
int get_width(Range range, bool ignore_invis = true) const
{return get_size(range, ignore_invis).width;}
//: Returns the height of the entire buffer, or a sub-Range.
//return: The height in pixels.
//param range: A subsection of the glyphs vector to get the height of.
//param idx: The vector index of a single glyph to get the height of.
//param ignore_invis: If true, ignores invisible glyphs (glyphs without an actual visual glyph in the font)
int get_height(bool ignore_invis = true) const
{return get_height(Range(*this), ignore_invis);}
int get_height(int idx, bool ignore_invis = true) const
{return get_height(Range(idx, idx+1), ignore_invis);}
int get_height(Range range, bool ignore_invis = true) const
{return get_size(range, ignore_invis).height;}
//: Returns the size of the entire buffer, or a sub-Range.
//return: The size in pixels.
//param range: A subsection of the glyphs vector to get the size of.
//param idx: The vector index of a single glyph to get the size of.
//param ignore_invis: If true, ignores invisible glyphs (glyphs without an actual visual glyph in the font)
CL_Size get_size(bool ignore_invis = true) const
{return get_size(Range(*this), ignore_invis);}
CL_Size get_size(int idx, bool ignore_invis = true) const
{return get_size(Range(idx, idx+1), ignore_invis);}
CL_Size get_size(Range range, bool ignore_invis = true) const
{return internal_rect(range, ignore_invis).get_size();}
//: Returns current angle.
//- <p> This rotates the entire glyph field when drawing.
//- The fonts' glyph rotation origin must be origin_top_left:0:0 for this
//- to produce legible results. See CL_Font::set_glyph_rotation_hotspot(). </p>
float get_angle() const
{return rot_angle;}
//: Returns scale for x and y.
//- <p> 1.0f is normal scale, 2.0f is twice the size, etc. </p>
void get_scale(float &x, float &y) const
{x = scale_x; y = scale_y;}
//: Returns translation hotspot for the entire glyph field.
void get_alignment(CL_Origin &origin, int &x, int &y) const
{origin = trans_origin; x = trans_x; y = trans_y;}
//: Returns rotation hotspot for the entire glyph field.
void get_rotation_hotspot(CL_Origin &origin, int &x, int &y) const
{origin = rot_origin; x = rot_x; y = rot_y;}
//: Returns the area that would be drawn to if a draw were performed.
//return: The area into which any pixels would be drawn. If buffer is empty, returns a rectangle with zero size.
//param x, y: Anchor position to start "drawing" at. Actual rendering position depends on the alignment mode.
//param dest: Rectangle to render glyphs in. The glyphs will be positioned within the rectangle depending on the alignment mode.
//param range: The subsection of the glyphs vector to use.
//param ignore_invis: If true, ignores invisible glyphs (glyphs without an actual visual glyph in the font)
CL_Rect bounding_rect(int x = 0, int y = 0, bool ignore_invis = true) const
{return bounding_rect(Range(*this), x, y, ignore_invis);}
CL_Rect bounding_rect(Range range, int x = 0, int y = 0, bool ignore_invis = true) const
{return bounding_rect(range, CL_Rect(x, y, x, y), ignore_invis);}
CL_Rect bounding_rect(CL_Rect dest, bool ignore_invis = true) const
{return bounding_rect(Range(*this), dest, ignore_invis);}
CL_Rect bounding_rect(Range range, CL_Rect dest, bool ignore_invis = true) const;
//: Returns the area occupied by glyphs inside the glyph buffer's coordinate space.
//return: The area occupied by all glyphs, inside the buffer. If buffer is empty, returns a rectangle with zero size.
//param range: The subsection of the glyphs vector to get the internal bounding rect of.
//param idx: The vector index of a single glyph to get the internal bounding rect of.
//param ignore_invis: If true, ignores invisible glyphs (glyphs without an actual visual glyph in the font)
CL_Rect internal_rect(bool ignore_invis = true) const
{return internal_rect(Range(*this), ignore_invis);}
CL_Rect internal_rect(int idx, bool ignore_invis = true) const
{return internal_rect(Range(idx, idx+1), ignore_invis);}
CL_Rect internal_rect(Range range, bool ignore_invis = true) const;
//: Returns a vector of CL_GlyphBuffer::Range, each of which contains one line.
//param range: The subsection of the glyphs vector to look through, which is expanded both ways.
//- <p> The CL_GlyphBuffer's contents (the glyphs vector, the font markers map, and the effects maps),
//- if any, must not have been created/altered by anything but CL_Font::draw_to_gb() or CL_TextStyler::draw_to_gb()
//- or the CL_GlyphBuffer justification functions or using CL_GlyphBuffer::remove to take glyphs off the end
//- for this method to work.</p>
std::vector<Range> get_lines() const
{return get_lines(Range(*this));}
std::vector<Range> get_lines(Range range) const;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -