1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 06:40:45 +00:00

Add a simple Font class.

This commit is contained in:
Andreas Kling 2018-10-11 23:45:57 +02:00
parent a6e0577f30
commit 110d01941a
6 changed files with 79 additions and 22 deletions

31
Widgets/Font.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "Font.h"
#include "Peanut8x10.h"
#include <AK/RetainPtr.h>
#include <cstdio>
Font& Font::defaultFont()
{
static auto* f = adopt(*new Font(Peanut8x10::glyphs, Peanut8x10::glyphWidth, Peanut8x10::glyphHeight, Peanut8x10::firstGlyph, Peanut8x10::lastGlyph)).leakRef();
return *f;
}
Font::Font(const char* const* glyphs, unsigned glyphWidth, unsigned glyphHeight, byte firstGlyph, byte lastGlyph)
: m_glyphs(glyphs)
, m_glyphWidth(glyphWidth)
, m_glyphHeight(glyphHeight)
, m_firstGlyph(firstGlyph)
, m_lastGlyph(lastGlyph)
{
}
Font::~Font()
{
}
const char* Font::glyph(char ch) const
{
if (ch < m_firstGlyph || ch > m_lastGlyph)
return nullptr;
return m_glyphs[(unsigned)ch - m_firstGlyph];
}

27
Widgets/Font.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
#include <AK/Retainable.h>
#include <AK/Types.h>
class Font : public Retainable<Font> {
public:
static Font& defaultFont();
~Font();
const char* glyph(char) const;
unsigned glyphWidth() const { return m_glyphWidth; }
unsigned glyphHeight() const { return m_glyphHeight; }
private:
Font(const char* const* glyphs, unsigned glyphWidth, unsigned glyphHeight, byte firstGlyph, byte lastGlyph);
const char* const* m_glyphs { nullptr };
unsigned m_glyphWidth { 0 };
unsigned m_glyphHeight { 0 };
byte m_firstGlyph { 0 };
byte m_lastGlyph { 0 };
};

View File

@ -20,6 +20,7 @@ VFS_OBJS = \
Button.o \
TerminalWidget.o \
WindowManager.o \
Font.o \
test.o
OBJS = $(AK_OBJS) $(VFS_OBJS)

View File

@ -1,19 +1,13 @@
#include "Painter.h"
#include "FrameBufferSDL.h"
#include "Widget.h"
#include "Font.h"
#include <AK/Assertions.h>
#include <SDL.h>
#if 0
#include "Peanut8x8.h"
#define FONT_NAMESPACE Peanut8x8
#else
#include "Peanut8x10.h"
#define FONT_NAMESPACE Peanut8x10
#endif
Painter::Painter(Widget& widget)
: m_widget(widget)
, m_font(Font::defaultFont())
{
}
@ -66,31 +60,31 @@ void Painter::drawText(const Rect& rect, const String& text, TextAlignment align
if (alignment == TextAlignment::TopLeft) {
point = rect.location();
point.moveBy(m_widget.x(), m_widget.y());;
point.moveBy(m_widget.x(), m_widget.y());
} else if (alignment == TextAlignment::Center) {
int textWidth = text.length() * FONT_NAMESPACE::fontWidth;
int textWidth = text.length() * m_font.glyphWidth();
point = rect.center();
point.moveBy(-(textWidth / 2), -(FONT_NAMESPACE::fontWidth / 2));
point.moveBy(-(textWidth / 2), -(m_font.glyphWidth() / 2));
point.moveBy(m_widget.x(), m_widget.y());
} else {
ASSERT_NOT_REACHED();
}
for (int row = 0; row < FONT_NAMESPACE::fontHeight; ++row) {
for (int row = 0; row < m_font.glyphHeight(); ++row) {
int y = point.y() + row;
dword* bits = scanline(y);
for (unsigned i = 0; i < text.length(); ++i) {
byte ch = text[i];
if (ch == ' ')
continue;
if (ch < FONT_NAMESPACE::firstCharacter || ch > FONT_NAMESPACE::lastCharacter) {
const char* glyph = m_font.glyph(ch);
if (!ch) {
printf("Font doesn't have 0x%02x ('%c')\n", ch, ch);
ASSERT_NOT_REACHED();
}
const char* fontCharacter = FONT_NAMESPACE::font[ch - FONT_NAMESPACE::firstCharacter];
int x = point.x() + i * FONT_NAMESPACE::fontWidth;
for (unsigned j = 0; j < FONT_NAMESPACE::fontWidth; ++j) {
char fc = fontCharacter[row * FONT_NAMESPACE::fontWidth + j];
int x = point.x() + i * m_font.glyphWidth();
for (unsigned j = 0; j < m_font.glyphWidth(); ++j) {
char fc = glyph[row * m_font.glyphWidth() + j];
if (fc == '#')
bits[x + j] = color.value();
}

View File

@ -5,6 +5,7 @@
#include "Rect.h"
#include <AK/String.h>
class Font;
class Widget;
class Painter {
@ -16,6 +17,9 @@ public:
void drawRect(const Rect&, Color);
void drawText(const Rect&, const String&, TextAlignment = TextAlignment::TopLeft, const Color& = Color());
const Font& font() const;
private:
Widget& m_widget;
Font& m_font;
};

View File

@ -2,12 +2,12 @@
namespace Peanut8x10 {
static constexpr char firstCharacter = '!';
static constexpr char lastCharacter = '~';
static constexpr byte fontWidth = 8;
static constexpr byte fontHeight = 10;
static constexpr char firstGlyph = '!';
static constexpr char lastGlyph = '~';
static constexpr byte glyphWidth = 8;
static constexpr byte glyphHeight = 10;
static constexpr const char* font[] {
static constexpr const char* glyphs[] {
" ## "
" ## "