📄 t1aaset.c
字号:
/*-------------------------------------------------------------------------- ----- File: t1aaset.c ----- Author: Rainer Menzner (Rainer.Menzner@web.de) Subsampling based on code by Raph Levien (raph@acm.org) ----- Date: 2001-04-01 ----- Description: This file is part of the t1-library. It contains functions for antialiased setting of characters and strings of characters. ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2001. As of version 0.5, t1lib is distributed under the GNU General Public Library Lincense. The conditions can be found in the files LICENSE and LGPL, which should reside in the toplevel directory of the distribution. Please note that there are parts of t1lib that are subject to other licenses: The parseAFM-package is copyrighted by Adobe Systems Inc. The type1 rasterizer is copyrighted by IBM and the X11-consortium. ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-) ----- Credits: I want to thank IBM and the X11-consortium for making their rasterizer freely available. Also thanks to Piet Tutelaers for his ps2pk, from which I took the rasterizer sources in a format independent from X11. Thanks to all people who make free software living!--------------------------------------------------------------------------*/ #define T1AASET_C#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#if defined(_MSC_VER)# include <io.h># include <sys/types.h># include <sys/stat.h>#else# include <unistd.h>#endif#include <stdlib.h>#include <math.h>#include <string.h>#include "../type1/ffilest.h"#include "../type1/types.h"#include "parseAFM.h" #include "../type1/objects.h"#include "../type1/spaces.h"#include "../type1/util.h"#include "../type1/fontfcn.h"#include "../type1/regions.h"#include "t1types.h"#include "t1extern.h"#include "t1aaset.h"#include "t1set.h"#include "t1load.h"#include "t1finfo.h"#include "t1misc.h"#include "t1base.h"#include "t1outline.h"#define DEFAULTBPP 8/* As a fall back */#ifndef T1_AA_TYPE16 #define T1_AA_TYPE16 short#endif#ifndef T1_AA_TYPE32 #define T1_AA_TYPE32 int#endif/* In the following arrays take the gray values. Entry 0 is associated with the white (background) value and the max entry is the black (foreground) value. */static unsigned T1_AA_TYPE32 gv[5]={0,0,0,0,0};static unsigned T1_AA_TYPE32 gv_h[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};static unsigned T1_AA_TYPE32 gv_n[2]={0,0};static int T1aa_level=T1_AA_LOW; /* The default value */static T1_AA_TYPE32 T1aa_lut[625];static int T1aa_count[256];static T1_AA_TYPE32 T1aa_h_lut[289];static int T1aa_h_count[256];static T1_AA_TYPE32 T1aa_n_lut[64];/* This global is for querying the current bg from other parts of t1lib */unsigned T1_AA_TYPE32 T1aa_bg=0;/* The limit values for smart antialiasing */float T1aa_smartlimit1=T1_AA_SMARTLIMIT1;float T1aa_smartlimit2=T1_AA_SMARTLIMIT2;int T1aa_SmartOn=0; /* We do not enable smart AA by default *//* T1_AAInit: This function must be called whenever the T1aa_gray_val or T1aa_bpp variables change, or the level changes. */static int T1_AAInit ( int level ){ int i; int i0, i1, i2, i3; int movelow=0, movehigh=0, indlow=0, indhigh=0; /* Note: movelow, movehigh, indlow and indhigh take care for proper byte swapping in dependence of endianess for level=4 */ if (level==T1_AA_NONE){ if (T1aa_bpp==8){ if (pFontBase->endian){ movelow=3; movehigh=2; } else{ movelow=0; movehigh=1; } } else if (T1aa_bpp==16){ if (pFontBase->endian){ movelow=1; movehigh=0; } else{ movelow=0; movehigh=1; } } } if (level==T1_AA_HIGH){ if (T1aa_bpp==8){ if (pFontBase->endian){ indlow=17; indhigh=1; movelow=3; movehigh=2; } else{ indlow=1; indhigh=17; movelow=0; movehigh=1; } } else if (T1aa_bpp==16){ if (pFontBase->endian){ indlow=17; indhigh=1; movelow=1; movehigh=0; } else{ indlow=1; indhigh=17; movelow=0; movehigh=1; } } else if (T1aa_bpp==32){ indlow=1; indhigh=17; } for (i = 0; i < 256; i++) { T1aa_h_count[i] = 0; if (i & 0x80) T1aa_h_count[i] += indhigh; if (i & 0x40) T1aa_h_count[i] += indhigh; if (i & 0x20) T1aa_h_count[i] += indhigh; if (i & 0x10) T1aa_h_count[i] += indhigh; if (i & 0x08) T1aa_h_count[i] += indlow; if (i & 0x04) T1aa_h_count[i] += indlow; if (i & 0x02) T1aa_h_count[i] += indlow; if (i & 0x01) T1aa_h_count[i] += indlow; } } if (level == 2 && T1aa_bpp == 8) { for (i0 = 0; i0 < 5; i0++) for (i1 = 0; i1 < 5; i1++) for (i2 = 0; i2 < 5; i2++) for (i3 = 0; i3 < 5; i3++) { ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4] = gv[i3]; ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 1] = gv[i2]; ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 2] = gv[i1]; ((char *)T1aa_lut)[(((i0 * 5 + i1) * 5 + i2) * 5 + i3) * 4 + 3] = gv[i0]; } for (i = 0; i < 256; i++) { T1aa_count[i] = 0; if (i & 0x80) T1aa_count[i] += 125; if (i & 0x40) T1aa_count[i] += 125; if (i & 0x20) T1aa_count[i] += 25; if (i & 0x10) T1aa_count[i] += 25; if (i & 0x08) T1aa_count[i] += 5; if (i & 0x04) T1aa_count[i] += 5; if (i & 0x02) T1aa_count[i] += 1; if (i & 0x01) T1aa_count[i] += 1; } return(0); } else if (level == 2 && T1aa_bpp == 16) { for (i0 = 0; i0 < 5; i0++) for (i1 = 0; i1 < 5; i1++) { ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2] = gv[i1]; ((T1_AA_TYPE16 *)T1aa_lut)[(i0 * 5 + i1) * 2 + 1] = gv[i0]; } for (i = 0; i < 256; i++) { T1aa_count[i] = 0; if (i & 0x80) T1aa_count[i] += 160; if (i & 0x40) T1aa_count[i] += 160; if (i & 0x20) T1aa_count[i] += 32; if (i & 0x10) T1aa_count[i] += 32; if (i & 0x08) T1aa_count[i] += 5; if (i & 0x04) T1aa_count[i] += 5; if (i & 0x02) T1aa_count[i] += 1; if (i & 0x01) T1aa_count[i] += 1; } return(0); } else if (level == 2 && T1aa_bpp == 32) { for (i0 = 0; i0 < 5; i0++) ((T1_AA_TYPE32 *)T1aa_lut)[i0] = gv[i0]; for (i = 0; i < 256; i++) { T1aa_count[i] = 0; if (i & 0x80) T1aa_count[i] += 512; if (i & 0x40) T1aa_count[i] += 512; if (i & 0x20) T1aa_count[i] += 64; if (i & 0x10) T1aa_count[i] += 64; if (i & 0x08) T1aa_count[i] += 8; if (i & 0x04) T1aa_count[i] += 8; if (i & 0x02) T1aa_count[i] += 1; if (i & 0x01) T1aa_count[i] += 1; } return(0); } else if (level == 4 && T1aa_bpp == 8) { for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movelow] = gv_h[i1]; ((char *)T1aa_h_lut)[(i0 * 17 + i1) * 4 + movehigh] = gv_h[i0]; } } return(0); } else if (level == 4 && T1aa_bpp == 16) { for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movelow] = gv_h[i1]; ((T1_AA_TYPE16 *)T1aa_h_lut)[(i0 * 17 + i1) * 2 + movehigh] = gv_h[i0]; } } return(0); } else if (level == 4 && T1aa_bpp == 32) { for (i0 = 0; i0 < 17; i0++){ /* i0 indexes higher nibble */ for (i1 = 0; i1 < 17; i1++){ /* i1 indixes lower nibble */ ((T1_AA_TYPE32 *)T1aa_h_lut)[(i0 * 17 + i1)] = gv_h[i1]; } } return(0); } else if (level == 1 && T1aa_bpp == 8) { for (i0=0; i0<16; i0++) { ((char *)T1aa_n_lut)[i0*4+movelow]=gv_n[i0 & 0x01]; ((char *)T1aa_n_lut)[i0*4+movelow+1]=gv_n[(i0>>1) & 0x01]; ((char *)T1aa_n_lut)[i0*4+movelow+2]=gv_n[(i0>>2) & 0x01]; ((char *)T1aa_n_lut)[i0*4+movelow+3]=gv_n[(i0>>3) & 0x01]; } return(0); } else if (level == 1 && T1aa_bpp == 16) { for (i0=0; i0<4; i0++) { ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2]=gv_n[i0 & 0x01]; ((T1_AA_TYPE16 *)T1aa_n_lut)[i0*2+1]=gv_n[(i0>>1) & 0x01]; } return(0); } else if (level == 1 && T1aa_bpp == 32) { for ( i0=0; i0<2; i0++) { ((T1_AA_TYPE32 *)T1aa_n_lut)[i0]=gv_n[i0]; } return(0); } else { /* unsupported combination of level and bpp -> we set T1_errno and put an entry into the logfile! */ T1_errno=T1ERR_INVALID_PARAMETER; sprintf( err_warn_msg_buf, "Unsupported AA specification: level=%d, bpp=%d", level, T1aa_bpp); T1_PrintLog( "T1_AAInit()", err_warn_msg_buf, T1LOG_WARNING); } return(1);}/* T1_AADoLine: Create a single scanline of antialiased output. The (x, y) arguments refer to the number of pixels in the input image to convert down. The width argument is the number of bytes separating scanlines in the input. The quantity hcorr describes the number of subpixels. It is the shift of the oversampled bitmap to the right */static void T1_AADoLine ( int level, int x, int y, int width, char *c_in_ptr, char *target_ptr, int hcorr ){ int i=0; int size; int count=0; int mod; unsigned char bcarry1=0, bcarry2=0, bcarry3=0, bcarry4=0; static char *align_buf = NULL; static int align_buf_size = 0; unsigned char *in_ptr; int new_size=55; register char *optr; /* We convert the input pointer to unsigned since we use it as index! */ in_ptr=(unsigned char*)c_in_ptr; if ((long)target_ptr & 3){ /* calculate new_size (size in bytes of output buffer */ if (level == T1_AA_LOW){ new_size=((x + hcorr + 1) >> 1) * (T1aa_bpp >> 3); } else{ /* T1_AA_HIGH */ new_size = ((x + hcorr + 3) >> 2) * (T1aa_bpp >> 3); } if (new_size > align_buf_size) { if (align_buf) free (align_buf); /* Note: we allocate 12 more than necessary to have tolerance at the end of line */ align_buf = (char *)malloc(new_size+12); align_buf_size = new_size; } optr = align_buf; } else optr = target_ptr; /* size: The number of valid byte in the input string, i.e., the number of bytes partially filled with pixels before shifting with hcorr. mod: Is 1 if after shifting with hcorr the last byte in the input line has an overflow. */ if (level == T1_AA_LOW) { size=(x+7)>>3; mod=(x+hcorr)>(size*8) ? 1 : 0; if (T1aa_bpp == 8) { if (y == 2){ for (i = 0; i < size; i++) { ((T1_AA_TYPE32 *)optr)[i] = T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; bcarry2=in_ptr[width]<<hcorr; } } else if (y == 1){ for (i = 0; i < size; i++) { ((T1_AA_TYPE32 *)optr)[i] = T1aa_lut[(T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])]; bcarry1=in_ptr[i]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; } } if (mod) { if (y == 2) ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1] + T1aa_count[bcarry2])]; else if (y == 1) ((T1_AA_TYPE32 *)optr)[i]=T1aa_lut[(T1aa_count[bcarry1])]; } } else if (T1aa_bpp == 16) { if (y == 2){ for (i = 0; i < size; i++) { count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)]; ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; bcarry2=in_ptr[width]<<hcorr; } } else if (y == 1){ for (i = 0; i < size; i++) { count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]; ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; bcarry1=in_ptr[i]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; } } if (mod){ if (y == 2) count = T1aa_count[bcarry1] + T1aa_count[bcarry2]; else if (y == 1) count = T1aa_count[bcarry1]; ((T1_AA_TYPE32 *)optr)[i * 2] = T1aa_lut[count & 31]; ((T1_AA_TYPE32 *)optr)[i * 2 + 1] = T1aa_lut[count >> 5]; } } else if (T1aa_bpp == 32) { if (y == 2){ for (i = 0; i < size; i++) { count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_count[(unsigned char)((in_ptr[i+width]<<hcorr)|bcarry2)]; ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; bcarry2=in_ptr[width]<<hcorr; } } else if (y == 1) { for (i = 0; i < size; i++) { count = T1aa_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)]; ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; bcarry1=in_ptr[i]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; } } if(mod) { if (y == 2){ count = T1aa_count[bcarry1] + T1aa_count[bcarry2]; } else if (y == 1){ count = T1aa_count[bcarry1]; } ((T1_AA_TYPE32 *)optr)[i * 4] = T1aa_lut[count & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 1] = T1aa_lut[(count >> 3) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 2] = T1aa_lut[(count >> 6) & 7]; ((T1_AA_TYPE32 *)optr)[i * 4 + 3] = T1aa_lut[(count >> 9) & 7]; } } } else if (level==T1_AA_HIGH){ size=(x+7)>>3; mod=(x+hcorr)>(size*8) ? 1 : 0; if (T1aa_bpp == 8) { if (y == 4){ for (i = 0; i < size; i++) { ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); bcarry3=in_ptr[i+2*width]>>(8-hcorr); bcarry4=in_ptr[i+3*width]>>(8-hcorr); } } else if (y == 3){ for (i = 0; i < size; i++) { ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)])]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); bcarry3=in_ptr[i+2*width]>>(8-hcorr); } } else if (y == 2){ for (i = 0; i < size; i++) { ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)])]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); } } else if (y == 1){ for (i = 0; i < size; i++) { ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)])]; bcarry1=in_ptr[i]>>(8-hcorr); } } if (mod) { if (y == 4) ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[bcarry1] + T1aa_h_count[bcarry2] + T1aa_h_count[bcarry3] + T1aa_h_count[bcarry4])]; else if (y == 3) ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[bcarry1] + T1aa_h_count[bcarry2] + T1aa_h_count[bcarry3])]; else if (y == 2) ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[bcarry1] + T1aa_h_count[bcarry2])]; else if (y == 1) ((T1_AA_TYPE16 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[bcarry1])]; } } else if (T1aa_bpp == 16) { if (y == 4){ for (i = 0; i < size; i++) { ((T1_AA_TYPE32 *)optr)[i] = T1aa_h_lut[(T1aa_h_count[(unsigned char)((in_ptr[i]<<hcorr)|bcarry1)] + T1aa_h_count[(unsigned char)((in_ptr[i + width]<<hcorr)|bcarry2)] + T1aa_h_count[(unsigned char)((in_ptr[i + 2*width]<<hcorr)|bcarry3)] + T1aa_h_count[(unsigned char)((in_ptr[i + 3*width]<<hcorr)|bcarry4)])]; bcarry1=in_ptr[i]>>(8-hcorr); bcarry2=in_ptr[i+width]>>(8-hcorr); bcarry3=in_ptr[i+2*width]>>(8-hcorr); bcarry4=in_ptr[i+3*width]>>(8-hcorr); } if (size==0){ bcarry1=in_ptr[0]<<hcorr; bcarry2=in_ptr[width]<<hcorr; bcarry3=in_ptr[2*width]<<hcorr; bcarry4=in_ptr[3*width]<<hcorr; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -