Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/wsfont Add support to rotate anti-aliased fonts.
details: https://anonhg.NetBSD.org/src/rev/8a5f0d8d536f
branches: trunk
changeset: 1026350:8a5f0d8d536f
user: rin <rin%NetBSD.org@localhost>
date: Fri Nov 19 23:55:16 2021 +0000
description:
Add support to rotate anti-aliased fonts.
wsfont_rotate_{cw,ccw}_internal() have been cleaned up and unified into
new static function wsfont_rotate_internal().
diffstat:
sys/dev/wsfont/wsfont.c | 158 ++++++++++++++++-------------------------------
1 files changed, 54 insertions(+), 104 deletions(-)
diffs (222 lines):
diff -r e4f98498c26a -r 8a5f0d8d536f sys/dev/wsfont/wsfont.c
--- a/sys/dev/wsfont/wsfont.c Fri Nov 19 23:51:16 2021 +0000
+++ b/sys/dev/wsfont/wsfont.c Fri Nov 19 23:55:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wsfont.c,v 1.72 2021/11/19 23:50:39 rin Exp $ */
+/* $NetBSD: wsfont.c,v 1.73 2021/11/19 23:55:16 rin Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.72 2021/11/19 23:50:39 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.73 2021/11/19 23:55:16 rin Exp $");
#include "opt_wsfont.h"
@@ -418,15 +418,15 @@
#if NRASOPS_ROTATION > 0
-struct wsdisplay_font *wsfont_rotate_cw_internal(struct wsdisplay_font *);
-struct wsdisplay_font *wsfont_rotate_ccw_internal(struct wsdisplay_font *);
-
-struct wsdisplay_font *
-wsfont_rotate_cw_internal(struct wsdisplay_font *font)
+static struct wsdisplay_font *
+wsfont_rotate_internal(struct wsdisplay_font *font, int rotate)
{
- int b, n, r, namelen, newstride;
struct wsdisplay_font *newfont;
- char *newname, *newbits;
+ char *newname, *newdata;
+ u_char *ch, *newch, *p, *newp;
+ int namelen, newstride, n, h, w;
+ u_char bit;
+ bool alpha = FONT_IS_ALPHA(font), cw = (rotate == WSFONT_ROTATE_CW);
/* Duplicate the existing font... */
newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK);
@@ -436,37 +436,58 @@
namelen = strlen(font->name) + 4;
newname = malloc(namelen, M_DEVBUF, M_WAITOK);
strlcpy(newname, font->name, namelen);
- strlcat(newname, "cw", namelen);
+ strlcat(newname, cw ? "cw" : "ccw", namelen);
newfont->name = newname;
/* Allocate a buffer big enough for the rotated font. */
- newstride = (font->fontheight + 7) / 8;
- newbits = malloc(newstride * font->fontwidth * font->numchars,
+ newstride = alpha ? font->fontheight : howmany(font->fontheight, 8);
+ newdata = malloc(newstride * font->fontwidth * font->numchars,
M_DEVBUF, M_WAITOK|M_ZERO);
- /* Rotate the font a bit at a time. */
- for (n = 0; n < font->numchars; n++) {
- unsigned char *ch = (unsigned char *)font->data +
- (n * font->stride * font->fontheight);
-
- for (r = 0; r < font->fontheight; r++) {
- for (b = 0; b < font->fontwidth; b++) {
- unsigned char *rb;
+#define BYTE_OFFSET(x, alpha) ((alpha) ? (x) : (x) / 8)
+#define BIT_FROM_LEFT(x) __BIT(7 - ((x) % 8))
+#define BIT_FROM_RIGHT(x) __BIT((x) % 8)
- rb = ch + (font->stride * r) + (b / 8);
- if (*rb & (0x80 >> (b % 8))) {
- unsigned char *rrb;
-
- rrb = newbits + newstride - 1 - (r / 8)
- + (n * newstride * font->fontwidth)
- + (newstride * b);
- *rrb |= (1 << (r % 8));
+ /* Rotate the font a pixel at a time. */
+ for (n = 0; n < font->numchars; n++) {
+ ch = (u_char *)font->data +
+ (n * font->stride * font->fontheight);
+ newch = newdata +
+ (n * newstride * font->fontwidth);
+ for (h = 0; h < font->fontheight; h++) {
+ for (w = 0; w < font->fontwidth; w++) {
+ p = ch + (h * font->stride) +
+ BYTE_OFFSET(w, alpha);
+ if (cw) {
+ /* Rotate clockwise. */
+ newp = newch +
+ (w * newstride) +
+ (newstride - 1 -
+ BYTE_OFFSET(h, alpha));
+ bit = BIT_FROM_RIGHT(h);
+ } else {
+ /* Rotate counter-clockwise. */
+ newp = newch +
+ ((font->fontwidth - 1 - w) *
+ newstride) +
+ BYTE_OFFSET(h, alpha);
+ bit = BIT_FROM_LEFT(h);
+ }
+ if (alpha) {
+ *newp = *p;
+ } else {
+ if (*p & BIT_FROM_LEFT(w))
+ *newp |= bit;
}
}
}
}
- newfont->data = newbits;
+#undef BYTE_OFFSET
+#undef BIT_FROM_LEFT
+#undef BIT_FROM_RIGHT
+
+ newfont->data = newdata;
/* Update font sizes. */
newfont->stride = newstride;
@@ -478,73 +499,7 @@
* If we seem to have rotated this font already, drop the
* new one...
*/
- free(newbits, M_DEVBUF);
- free(newfont, M_DEVBUF);
- newfont = NULL;
- }
-
- return (newfont);
-}
-
-struct wsdisplay_font *
-wsfont_rotate_ccw_internal(struct wsdisplay_font *font)
-{
- int b, n, r, namelen, newstride;
- struct wsdisplay_font *newfont;
- char *newname, *newbits;
-
- /* Duplicate the existing font... */
- newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK);
-
- *newfont = *font;
-
- namelen = strlen(font->name) + 4;
- newname = malloc(namelen, M_DEVBUF, M_WAITOK);
- strlcpy(newname, font->name, namelen);
- strlcat(newname, "ccw", namelen);
- newfont->name = newname;
-
- /* Allocate a buffer big enough for the rotated font. */
- newstride = (font->fontheight + 7) / 8;
- newbits = malloc(newstride * font->fontwidth * font->numchars,
- M_DEVBUF, M_WAITOK|M_ZERO);
-
- /* Rotate the font a bit at a time. */
- for (n = 0; n < font->numchars; n++) {
- unsigned char *ch = (unsigned char *)font->data +
- (n * font->stride * font->fontheight);
-
- for (r = 0; r < font->fontheight; r++) {
- for (b = 0; b < font->fontwidth; b++) {
- unsigned char *rb;
-
- rb = ch + (font->stride * r) + (b / 8);
- if (*rb & (0x80 >> (b % 8))) {
- unsigned char *rrb;
- int w = font->fontwidth;
-
- rrb = newbits + (r / 8)
- + (n * newstride * w)
- + (newstride * (w - 1 - b));
- *rrb |= (0x80 >> (r % 8));
- }
- }
- }
- }
-
- newfont->data = newbits;
-
- /* Update font sizes. */
- newfont->stride = newstride;
- newfont->fontwidth = font->fontheight;
- newfont->fontheight = font->fontwidth;
-
- if (wsfont_add(newfont, 0) != 0) {
- /*
- * If we seem to have rotated this font already, drop the
- * new one...
- */
- free(newbits, M_DEVBUF);
+ free(newdata, M_DEVBUF);
free(newfont, M_DEVBUF);
newfont = NULL;
}
@@ -568,13 +523,8 @@
switch (rotate) {
case WSFONT_ROTATE_CW:
- font = wsfont_rotate_cw_internal(origfont->font);
- if (font == NULL)
- return (-1);
- break;
-
case WSFONT_ROTATE_CCW:
- font = wsfont_rotate_ccw_internal(origfont->font);
+ font = wsfont_rotate_internal(origfont->font, rotate);
if (font == NULL)
return (-1);
break;
@@ -583,9 +533,9 @@
default:
return (-1);
}
- /* rotation works only with bitmap fonts so far */
+
ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight,
- font->stride, 0, 0, WSFONT_FIND_BITMAP);
+ font->stride, 0, 0, WSFONT_FIND_ALL);
return (ncookie);
}
Home |
Main Index |
Thread Index |
Old Index