1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-25 07:40:40 -07:00

Initial revision

This commit is contained in:
Geoff Voelker 1999-01-22 19:42:26 +00:00
parent 7ebca6a618
commit 7b416d4284
2 changed files with 678 additions and 0 deletions

604
src/w32bdf.c Normal file
View file

@ -0,0 +1,604 @@
/* Implementation of BDF font handling on the Microsoft W32 API.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Emacs 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Based heavily on code by H. Miyashita for Meadow (a descendant of
MULE for W32). */
#include <windows.h>
#include "config.h"
#include "lisp.h"
#include "charset.h"
#include "fontset.h"
#include "blockinput.h"
#include "w32gui.h"
#include "w32term.h"
#include "w32bdf.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
void w32_free_bdf_font(bdffont *fontp);
bdffont *w32_init_bdf_font(char *filename);
static int
search_file_line(char *key, char *start, int len, char **val, char **next)
{
int linelen;
unsigned char *p, *q;
p = memchr(start, '\n', len);
if (!p) return -1;
for (;start < p;start++)
{
if ((*start != ' ') || (*start != '\t')) break;
}
linelen = p - start + 1;
*next = p + 1;
if (strncmp(start, key, min(strlen(key), linelen)) == 0)
{
*val = start + strlen(key);
return 1;
}
return 0;
}
static int
proceed_file_line(char *key, char *start, int *len, char **val, char **next)
{
int flag = 0;
do {
flag = search_file_line(key, start, *len, val, next);
*len -= (int)(*next - start);
start = *next;
}while(flag == 0);
if (flag == -1) return 0;
return 1;
}
static int
set_bdf_font_info(bdffont *fontp)
{
unsigned char *start, *p, *q;
int len, flag;
int bbw, bbh, bbx, bby;
int val1;
len = fontp->size;
start = fontp->font;
fontp->yoffset = 0;
fontp->relative_compose = 0;
fontp->default_ascent = 0;
flag = proceed_file_line("FONTBOUNDINGBOX", start, &len, &p, &q);
if (!flag) return 0;
bbw = strtol(p, &start, 10);
p = start;
bbh = strtol(p, &start, 10);
p = start;
bbx = strtol(p, &start, 10);
p = start;
bby = strtol(p, &start, 10);
fontp->llx = bbx;
fontp->lly = bby;
fontp->urx = bbw + bbx;
fontp->ury = bbh + bby;
fontp->width = bbw;
fontp->height = bbh;
start = q;
flag = proceed_file_line("STARTPROPERTIES", start, &len, &p, &q);
if (!flag) return 1;
do {
start = q;
if (search_file_line("PIXEL_SIZE", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->pixsz = val1;
}
else if (search_file_line("FONT_ASCENT", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->ury = val1;
}
else if (search_file_line("FONT_DESCENT", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->lly = -val1;
}
else if (search_file_line("_MULE_BASELINE_OFFSET", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->yoffset = val1;
}
else if (search_file_line("_MULE_RELATIVE_COMPOSE", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->relative_compose = val1;
}
else if (search_file_line("_MULE_DEFAULT_ASCENT", start, len, &p, &q) == 1)
{
val1 = atoi(p);
fontp->default_ascent = val1;
}
else
{
flag = search_file_line("ENDPROPERTIES", start, len, &p, &q);
}
if (flag == -1) return 0;
len -= (q - start);
}while(flag == 0);
start = q;
flag = proceed_file_line("CHARS", start, &len, &p, &q);
if (!flag) return 0;
fontp->seeked = q;
return 1;
}
bdffont*
w32_init_bdf_font(char *filename)
{
HANDLE hfile, hfilemap;
bdffont *bdffontp;
unsigned char *font;
BY_HANDLE_FILE_INFORMATION fileinfo;
int i;
hfile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile == INVALID_HANDLE_VALUE) return NULL;
if (!GetFileInformationByHandle(hfile, &fileinfo) ||
(fileinfo.nFileSizeHigh != 0) ||
(fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
{
CloseHandle(hfile);
error("Fail to open BDF file.");
}
hfilemap = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hfilemap == INVALID_HANDLE_VALUE)
{
CloseHandle(hfile);
error("Can't map font.");
}
font = MapViewOfFile(hfilemap, FILE_MAP_READ, 0, 0, 0);
if (!font)
{
CloseHandle(hfile);
CloseHandle(hfilemap);
error("Can't view font.");
}
bdffontp = (bdffont *) xmalloc(sizeof(bdffont));
for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
bdffontp->offset[i] = NULL;
bdffontp->size = fileinfo.nFileSizeLow;
bdffontp->font = font;
bdffontp->hfile = hfile;
bdffontp->hfilemap = hfilemap;
bdffontp->filename = (char*) xmalloc(strlen(filename) + 1);
strcpy(bdffontp->filename, filename);
if (!set_bdf_font_info(bdffontp))
{
w32_free_bdf_font(bdffontp);
error("Invalid BDF font!");
}
return bdffontp;
}
void
w32_free_bdf_font(bdffont *fontp)
{
int i;
UnmapViewOfFile(fontp->hfilemap);
CloseHandle(fontp->hfilemap);
CloseHandle(fontp->hfile);
xfree(fontp->filename);
for(i = 0;i < BDF_FIRST_OFFSET_TABLE;i++)
{
if (fontp->offset[i]) xfree(fontp->offset[i]);
}
xfree(fontp);
}
static unsigned char*
get_cached_char_offset(bdffont *fontp, int index)
{
unsigned char **offset1;
unsigned char *offset2;
int i;
if (index > 0xffff)
return NULL;
offset1 = fontp->offset[BDF_FIRST_OFFSET(index)];
if (!offset1)
return NULL;
offset2 = offset1[BDF_SECOND_OFFSET(index)];
if (offset2) return offset2;
return NULL;
}
static void
cache_char_offset(bdffont *fontp, int index, unsigned char *offset)
{
unsigned char **offset1;
int i;
if (index > 0xffff)
return;
offset1 = fontp->offset[BDF_FIRST_OFFSET(index)];
if (!offset1)
{
offset1 = fontp->offset[BDF_FIRST_OFFSET(index)] =
(unsigned char **) xmalloc(sizeof(unsigned char*) *
BDF_SECOND_OFFSET_TABLE);
memset(offset1, 0, sizeof(unsigned char*) * BDF_SECOND_OFFSET_TABLE);
}
offset1[BDF_SECOND_OFFSET(index)] = offset;
return;
}
static unsigned char*
seek_char_offset(bdffont *fontp, int index)
{
int len, flag, font_index;
unsigned char *start, *p, *q;
if (!fontp->seeked) return NULL;
start = fontp->seeked;
len = fontp->size - (start - fontp->font);
do {
flag = proceed_file_line("ENCODING", start, &len, &p, &q);
if (!flag)
{
fontp->seeked = NULL;
return NULL;
}
font_index = atoi(p);
cache_char_offset(fontp, font_index, q);
start = q;
} while (font_index != index);
fontp->seeked = q;
return q;
}
#define GET_HEX_VAL(x) ((isdigit(x)) ? ((x) - '0') : \
(((x) >= 'A') && ((x) <= 'Z')) ? ((x) - 'A' + 10) : \
(((x) >= 'a') && ((x) <= 'z')) ? ((x) - 'a' + 10) : \
(-1))
int
w32_get_bdf_glyph(bdffont *fontp, int index, int size, glyph_struct *glyph)
{
unsigned char *start, *p, *q, *bitmapp;
unsigned char val1, val2;
int i, j, len, flag;
start = get_cached_char_offset(fontp, index);
if (!start)
start = seek_char_offset(fontp, index);
if (!start)
return 0;
len = fontp->size - (start - fontp->font);
flag = proceed_file_line("DWIDTH", start, &len, &p, &q);
if (!flag)
return 0;
glyph->dwidth = atoi(p);
start = q;
flag = proceed_file_line("BBX", start, &len, &p, &q);
if (!flag)
return 0;
glyph->bbw = strtol(p, &start, 10);
p = start;
glyph->bbh = strtol(p, &start, 10);
p = start;
glyph->bbox = strtol(p, &start, 10);
p = start;
glyph->bboy = strtol(p, &start, 10);
if (size == 0) return 1;
start = q;
flag = proceed_file_line("BITMAP", start, &len, &p, &q);
if (!flag)
return 0;
p = q;
bitmapp = glyph->bitmap;
for(i = 0;i < glyph->bbh;i++)
{
q = memchr(p, '\n', len);
if (!q) return 0;
for(j = 0;((q > p) && (j < ((glyph->bbw + 7) / 8 )));j++)
{
val1 = GET_HEX_VAL(*p);
if (val1 == -1) return 0;
p++;
val2 = GET_HEX_VAL(*p);
if (val2 == -1) return 0;
p++;
size--;
if (size <= 0) return 0;
/* NAND Operation. */
*bitmapp++ = (unsigned char)~((val1 << 4) | val2);
}
/* CreateBitmap requires WORD alignment. */
if (j % 2)
{
*bitmapp++ = 0xff;
}
p = q + 1;
}
return 1;
}
int
w32_BDF_TextOut(bdffont *fontp, HDC hdc, int left,
int top, unsigned char *text, int dim, int bytelen,
int fixed_pitch_size)
{
int bitmap_size, index, btop;
unsigned char *textp;
glyph_struct glyph;
HDC hCompatDC = 0;
HBITMAP hBMP;
HBRUSH hFgBrush, hOrgBrush;
HANDLE holdobj, horgobj = 0;
UINT textalign;
int flag = 0;
bitmap_size = ((fontp->urx - fontp->llx) / 8 + 2) * (fontp->ury - fontp->lly)
+ 256;
glyph.bitmap = (unsigned char*) alloca(sizeof(unsigned char) * bitmap_size);
hCompatDC = CreateCompatibleDC(hdc);
textalign = GetTextAlign(hdc);
SaveDC(hdc);
hFgBrush = CreateSolidBrush(GetTextColor(hdc));
hOrgBrush = SelectObject(hdc, hFgBrush);
SetTextColor(hdc, RGB(0, 0, 0));
SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
textp = text;
while(bytelen > 0)
{
if (dim == 1)
{
index = *textp++;
bytelen--;
}
else
{
bytelen -= 2;
if (bytelen < 0) break;
index = MAKELENDSHORT(textp[1], textp[0]);
textp += 2;
}
if (!w32_get_bdf_glyph(fontp, index, bitmap_size, &glyph))
{
if (horgobj)
{
SelectObject(hCompatDC, horgobj);
DeleteObject(hBMP);
}
DeleteDC(hCompatDC);
return 0;
}
hBMP = CreateBitmap(glyph.bbw, glyph.bbh, 1, 1, glyph.bitmap);
if (textalign & TA_BASELINE)
{
btop = top - (glyph.bbh + glyph.bboy);
}
else if (textalign & TA_BOTTOM)
{
btop = top - glyph.bbh;
}
else
{
btop = top;
}
if (horgobj)
{
SelectObject(hCompatDC, hBMP);
DeleteObject(holdobj);
holdobj = hBMP;
}
else
{
horgobj = SelectObject(hCompatDC, hBMP);
holdobj = hBMP;
}
#if 0
BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, SRCCOPY);
#else
BitBlt(hdc, left, btop, glyph.bbw, glyph.bbh, hCompatDC, 0, 0, 0xB8074A);
#endif
if (fixed_pitch_size)
left += fixed_pitch_size;
else
left += glyph.dwidth;
}
SelectObject(hCompatDC, horgobj);
SelectObject(hdc, hOrgBrush);
DeleteObject(hFgBrush);
DeleteObject(hBMP);
DeleteDC(hCompatDC);
RestoreDC(hdc, -1);
return 1;
}
struct font_info *w32_load_bdf_font (struct frame *f, char *fontname,
int size, char* filename)
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
struct font_info *fontp;
XFontStruct *font;
bdffont* bdf_font;
bdf_font = w32_init_bdf_font (filename);
if (!bdf_font) return NULL;
font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
font->bdf = bdf_font;
font->hfont = 0;
/* Do we need to create the table? */
if (dpyinfo->font_table_size == 0)
{
dpyinfo->font_table_size = 16;
dpyinfo->font_table
= (struct font_info *) xmalloc (dpyinfo->font_table_size
* sizeof (struct font_info));
}
/* Do we need to grow the table? */
else if (dpyinfo->n_fonts
>= dpyinfo->font_table_size)
{
dpyinfo->font_table_size *= 2;
dpyinfo->font_table
= (struct font_info *) xrealloc (dpyinfo->font_table,
(dpyinfo->font_table_size
* sizeof (struct font_info)));
}
fontp = dpyinfo->font_table + dpyinfo->n_fonts;
/* Now fill in the slots of *FONTP. */
BLOCK_INPUT;
fontp->font = font;
fontp->font_idx = dpyinfo->n_fonts;
fontp->name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, fontp->name, strlen (fontname) + 1);
fontp->full_name = fontp->name;
fontp->size = FONT_WIDTH (font);
fontp->height = FONT_HEIGHT (font);
/* The slot `encoding' specifies how to map a character
code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
2:0xA020..0xFF7F). For the moment, we don't know which charset
uses this font. So, we set informatoin in fontp->encoding[1]
which is never used by any charset. If mapping can't be
decided, set FONT_ENCODING_NOT_DECIDED. */
fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
fontp->baseline_offset = bdf_font->yoffset;
fontp->relative_compose = bdf_font->relative_compose;
fontp->default_ascent = bdf_font->default_ascent;
UNBLOCK_INPUT;
dpyinfo->n_fonts++;
return fontp;
}
/* Check a file for an XFLD string describing it. */
int w32_BDF_to_x_font (char *file, char* xstr, int len)
{
HANDLE hfile, hfilemap;
BY_HANDLE_FILE_INFORMATION fileinfo;
unsigned char *font, *start, *p, *q;
int flag, size, retval = 0;
hfile = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile == INVALID_HANDLE_VALUE) return 0;
if (!GetFileInformationByHandle(hfile, &fileinfo) ||
(fileinfo.nFileSizeHigh != 0) ||
(fileinfo.nFileSizeLow > BDF_FILE_SIZE_MAX))
{
CloseHandle (hfile);
return 0;
}
size = fileinfo.nFileSizeLow;
hfilemap = CreateFileMapping (hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hfilemap == INVALID_HANDLE_VALUE)
{
CloseHandle (hfile);
return 0;
}
font = MapViewOfFile (hfilemap, FILE_MAP_READ, 0, 0, 0);
if (!font)
{
CloseHandle (hfile);
CloseHandle (hfilemap);
return 0;
}
start = font;
flag = proceed_file_line ("FONT ", start, &size, &p, &q);
if (flag)
{
/* If font provides a description of itself, check it is a
full XLFD before accepting it. */
int count = 0;
char *s;
for (s = p; s < q; s++)
if (*s == '\n')
break;
else if (*s == '-')
count++;
if (count == 14 && q - p - 1 <= len)
{
strncpy (xstr, p, q-p-1);
xstr[q-p-1] = '\0';
/* Files may have DOS line ends (ie still ^M on end). */
if (iscntrl(xstr[q-p-2]))
xstr[q-p-2] = '\0';
retval = 1;
}
}
CloseHandle (hfile);
CloseHandle (hfilemap);
return retval;
}

74
src/w32bdf.h Normal file
View file

@ -0,0 +1,74 @@
/* Definitions and header for handling BDF fonts on the Microsoft W32 API.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Emacs 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Based heavily on code by H. Miyashita for Meadow (a descendant of
MULE for W32). */
#ifndef __W32BDF_H__
#define __W32BDF_H__
#define BDF_FIRST_OFFSET_TABLE 0x200
#define BDF_SECOND_OFFSET_TABLE 0x80
#define BDF_SECOND_OFFSET(x) ((x) & 0x7f)
#define BDF_FIRST_OFFSET(x) (((x) >> 8) | (((x) & 0x80) << 1))
/* Structure of glyph information of one character. */
typedef struct
{
int dwidth; /* width in pixels */
int bbw, bbh, bbox, bboy; /* bounding box in pixels */
int bitmap_size; /* byte lengh of the following slots */
unsigned char *bitmap; /* */
} glyph_struct;
typedef struct
{
char *filename;
HANDLE hfile;
HANDLE hfilemap;
unsigned char *font;
unsigned char *seeked;
DWORD size;
unsigned char **offset[BDF_FIRST_OFFSET_TABLE];
int llx, lly, urx, ury; /* Font bounding box */
int yoffset;
int relative_compose;
int default_ascent;
int width;
int height;
int pixsz;
} bdffont;
#define BDF_FILE_SIZE_MAX 256*1024*1024 /* 256Mb */
#define BDF_FONT_FILE(font) (((bdffont*)(font))->filename)
#define MAKELENDSHORT(c1, c2) (unsigned short)((c1) | ((c2) << 8))
bdffont *w32_init_bdf_font (char *filename);
void w32_free_bdf_font (bdffont *fontp);
int w32_get_bdf_glyph (bdffont *fontp, int index, int size,
glyph_struct *glyph);
int w32_BDF_TextOut (bdffont *fontp, HDC hdc, int left,
int top, unsigned char *text, int dim,
int bytelen, int fixed_pitch_size);
int w32_BDF_to_x_font (char *file, char* xstr, int len);
#endif /* __W32BDF_H__ */