CML_Error CML_NodeFindContainer(CML_Node * node, char * path, CML_Node ** result) { CHECKPTR(node ); CHECKPTR(result); char next[256]; char curr[256]; path_curr(path, curr); path_next(path, next); uint32_t index; CHECKERR(CML_NodeFindIndex(node, curr, &index)); if (next[0]) /* go deeper */ CHECKERR(CML_NodeFindContainer(node->nodes[index], next, result)) else /* stay here */ { if ((node->nodes[index]->type == CML_TYPE_ARRAY) || (node->nodes[index]->type == CML_TYPE_HASH)) *result = node->nodes[index]; else return CML_ERROR_USER_BADTYPE; } return CML_ERROR_SUCCESS; }
CML_Error CML_NodeFind(CML_Node * node, char * path, CML_Node ** result, CML_Type type) { CHECKPTR(node ); CHECKTYP(type ); CHECKPTR(result); char next[1024]; char curr[1024]; path_curr(path, curr); path_next(path, next); uint32_t index; CHECKERR(CML_NodeFindIndex(node, curr, &index)); if (next[0]) /* go deeper */ CHECKERR(CML_NodeFind(node->nodes[index], next, result, type)) else /* stay here */ { if (node->nodes[index]->type == type) *result = node->nodes[index]; else return CML_ERROR_USER_BADTYPE; } return CML_ERROR_SUCCESS; }
size_t LogSequence2::load(const unsigned char *ptr, const unsigned char *ptrMax, ProgressListener *listener) { size_t count = 0; // Read type CHECKPTR(&ptr[count], ptrMax, 1); if(ptr[count]!=TYPE_SEQLOG) { throw "Trying to read a LOGArray but data is not LogArray"; } count++; // Read numbits CHECKPTR(&ptr[count], ptrMax, 1); numbits = ptr[count++]; // Read numentries uint64_t numentries64; count += csd::VByte::decode(&ptr[count], ptrMax, &numentries64); // Validate Checksum Header CRC8 crch; crch.update(&ptr[0], count); CHECKPTR(&ptr[count], ptrMax, 1); if(crch.getValue()!=ptr[count++]) throw "Checksum error while reading LogSequence2 header."; // Update local variables and validate maxval = maxVal(numbits); numentries = (size_t) numentries64; if(numbits>sizeof(size_t)*8 || numentries64>std::numeric_limits<size_t>::max()) { throw "This data structure is too big for this machine"; } // Setup array of data arraysize = numBytesFor(numbits, numentries); array = (size_t *) &ptr[count]; count+=arraysize; IsMapped = true; if(&ptr[count]>=ptrMax) throw "LogSequence2 tries to read beyond the end of the file"; CHECKPTR(&ptr[count], ptrMax, 4); count+=4; // CRC of data return count; }
void TConfigFile::appendLine(const char* s){ CHECKPTR(s); if (s[0] != 0){ //wenigstens ein newline sollte da sein TString *str = new TString(s); str->stripWhiteSpace(); text << str; } }
int draw_bitmap(TTF_Bitmap *canvas, TTF_Bitmap *bitmap, int x, int y) { CHECKPTR(canvas); CHECKPTR(bitmap); if (!IN(x, 0, canvas->w-1) || !IN(y, 0, canvas->h-1)) { warn("failed to draw bitmap out of bounds"); return FAILURE; } /* Out of bounds checking is also done in bitmap_set,_get() */ for (int yb = 0; yb < bitmap->h; yb++) { for (int xb = 0; xb < bitmap->w; xb++) { bitmap_set(canvas, x+xb, y+yb, bitmap_get(bitmap, xb, yb)); } } return SUCCESS; }
CML_Error CML_NodeFindIndex(CML_Node * node, char * name, uint32_t * index) { CHECKPTR(node ); CHECKSTR(name ); CHECKPTR(index); CHECKJAR(node ); uint32_t i; for (i = 0; i < node->ncount; i++) if ((node->nodes[i]->name) && (!strcmp(node->nodes[i]->name, name))) { *index = i; return CML_ERROR_SUCCESS; } return CML_ERROR_USER_BADSTRING; }
int scale_glyph(TTF_Font *font, TTF_Glyph *glyph) { CHECKPTR(font); CHECKPTR(glyph); if (font->point < 0) { /* raster_init() has not been called yet */ warn("font rasterizer has not been initialized"); return FAILURE; } if (!glyph->outline) { load_glyph_outline(glyph); } else if (glyph->outline->point == font->point) { /* glyph is already scaled */ return SUCCESS; } scale_outline(font, glyph->outline); return SUCCESS; }
static void test_VarFormatNumber(void) { static const WCHAR szSrc1[] = { '1','\0' }; static const WCHAR szResult1[] = { '1','.','0','0','\0' }; static const WCHAR szSrc2[] = { '-','1','\0' }; static const WCHAR szResult2[] = { '(','1','.','0','0',')','\0' }; char buff[8]; HRESULT hres; VARIANT v; BSTR str = NULL; CHECKPTR(VarFormatNumber); GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char)); if (buff[0] != '.' || buff[1]) { trace("Skipping VarFormatNumber tests as decimal separator is '%s'\n", buff); return; } FMT_NUMBER(VT_I1, V_I1); FMT_NUMBER(VT_UI1, V_UI1); FMT_NUMBER(VT_I2, V_I2); FMT_NUMBER(VT_UI2, V_UI2); FMT_NUMBER(VT_I4, V_I4); FMT_NUMBER(VT_UI4, V_UI4); if (HAVE_OLEAUT32_I8) { FMT_NUMBER(VT_I8, V_I8); FMT_NUMBER(VT_UI8, V_UI8); } FMT_NUMBER(VT_R4, V_R4); FMT_NUMBER(VT_R8, V_R8); FMT_NUMBER(VT_BOOL, V_BOOL); V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString(szSrc1); hres = pVarFormatNumber(&v,2,0,0,0,0,&str); ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres); if (hres == S_OK) ok(str && strcmpW(str, szResult1) == 0, "VarFormatNumber (bstr): string different\n"); SysFreeString(V_BSTR(&v)); SysFreeString(str); V_BSTR(&v) = SysAllocString(szSrc2); hres = pVarFormatNumber(&v,2,0,-1,0,0,&str); ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres); if (hres == S_OK) ok(str && strcmpW(str, szResult2) == 0, "VarFormatNumber (-bstr): string different\n"); SysFreeString(V_BSTR(&v)); SysFreeString(str); }
static int scale_outline(TTF_Font *font, TTF_Outline *outline) { CHECKPTR(outline); int scale_x, scale_y; if (font->raster_flags & RENDER_FPAA) { /* 4 samples / pixel */ scale_x = scale_y = 2; } else if (font->raster_flags & RENDER_ASPAA) { /* 3 samples / pixel */ scale_x = 3; scale_y = 1; } else { /* 1 sample / pixel */ scale_x = scale_y = 1; } for (int i = 0; i < outline->num_contours; i++) { TTF_Contour *contour = &outline->contours[i]; CHECKPTR(contour); for (int j = 0; j < contour->num_segments; j++) { TTF_Segment *segment = &contour->segments[j]; CHECKPTR(segment); int k; for (k = 0; k < segment->num_points; k++) { segment->x[k] = round_pixel(scale_x * funit_to_pixel(font, segment->x[k])); segment->y[k] = round_pixel(scale_y * funit_to_pixel(font, segment->y[k])); } } } /* Round outline bounding box to nearest whole pixel value */ outline->x_min = symroundf(scale_x * funit_to_pixel(font, outline->x_min)); outline->y_min = symroundf(scale_y * funit_to_pixel(font, outline->y_min)); outline->x_max = symroundf(scale_x * funit_to_pixel(font, outline->x_max)); outline->y_max = symroundf(scale_y * funit_to_pixel(font, outline->y_max)); outline->point = font->point; return SUCCESS; }
int init_scanline(TTF_Scan_Line *scanline, int base_size) { CHECKPTR(scanline); RETINIT(SUCCESS); scanline->x = malloc(base_size * sizeof(*scanline->x)); CHECKFAIL(scanline->x, warnerr("failed to alloc scanline")); scanline->size_x = base_size; scanline->num_intersections = 0; RETFAIL(free_scanline(scanline)); }
static int add_intersection(TTF_Scan_Line *scanline, float x) { CHECKPTR(scanline); RETINIT(SUCCESS); if (scanline->num_intersections+1 > scanline->size_x) { /* Increase size of scan-line storage for new intersection. */ scanline->x = realloc(scanline->x, (scanline->size_x * 2) * sizeof(*scanline->x)); CHECKFAIL(scanline->x, warnerr("failed to adjust scanline size")); scanline->size_x *= 2; } scanline->x[scanline->num_intersections++] = x; RET; }
SEXP R_deque_to_Rlist(SEXP deque_ptr) { deque_t *dl = (deque_t *) getRptr(deque_ptr); CHECKPTR(dl); const int len = dl->len; list_t *l = dl->start; SEXP Rlist; PROTECT(Rlist = allocVector(VECSXP, len)); for (int i=0; i<len; i++) { append_item_to_Rlist(Rlist, i, l->data); l = l->next; } UNPROTECT(1); return Rlist; }
int set_bitmap_gamma(TTF_Bitmap *bitmap, float gamma) { CHECKPTR(bitmap); if (gamma == 0) { return FAILURE; } float correction = 1 / gamma; for (int y = 0; y < bitmap->h; y++) { for (int x = 0; x < bitmap->w; x++) { uint32_t pixel = bitmap_get(bitmap, x, y); uint8_t *b = (uint8_t *)&pixel; b[0] = 255 * powf((b[0] / (float)255), correction); b[1] = 255 * powf((b[1] / (float)255), correction); b[2] = 255 * powf((b[2] / (float)255), correction); bitmap_set(bitmap, x, y, pixel); } } return SUCCESS; }
static void test_VarWeekdayName(void) { char buff[256]; BSTR out = NULL; HRESULT hres; int iWeekday, fAbbrev, iFirstDay; BSTR dayNames[7][2]; /* Monday-Sunday, full/abbr */ DWORD defaultFirstDay; int firstDay; int day; int size; DWORD localeValue; CHECKPTR(VarWeekdayName); SetLastError(0xdeadbeef); GetLocaleInfoW(LOCALE_USER_DEFAULT, 0, NULL, 0); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("GetLocaleInfoW is not implemented\n"); return; } /* Initialize days' names */ for (day = 0; day <= 6; ++day) { for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) { localeValue = fAbbrev ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1; localeValue += day; size = GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, NULL, 0); dayNames[day][fAbbrev] = SysAllocStringLen(NULL, size - 1); GetLocaleInfoW(LOCALE_USER_DEFAULT, localeValue, dayNames[day][fAbbrev], size); } } /* Get the user's first day of week. 0=Monday, .. */ GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER, (LPWSTR)&defaultFirstDay, sizeof(defaultFirstDay) / sizeof(WCHAR)); /* Check invalid arguments */ VARWDN_F(0, 0, 4, 0, E_INVALIDARG); VARWDN_F(8, 0, 4, 0, E_INVALIDARG); VARWDN_F(4, 0, -1, 0, E_INVALIDARG); VARWDN_F(4, 0, 8, 0, E_INVALIDARG); hres = pVarWeekdayName(1, 0, 0, 0, NULL); ok(E_INVALIDARG == hres, "Null pointer: expected E_INVALIDARG, got 0x%08x\n", hres); /* Check all combinations */ pVarBstrCmp = (void*)GetProcAddress(hOleaut32, "VarBstrCmp"); if (pVarBstrCmp) for (iWeekday = 1; iWeekday <= 7; ++iWeekday) { for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) { /* 0 = Default, 1 = Sunday, 2 = Monday, .. */ for (iFirstDay = 0; iFirstDay <= 7; ++iFirstDay) { VARWDN_O(iWeekday, fAbbrev, iFirstDay, 0); if (iFirstDay == 0) firstDay = defaultFirstDay; else /* Translate from 0=Sunday to 0=Monday in the modulo 7 space */ firstDay = iFirstDay - 2; day = (7 + iWeekday - 1 + firstDay) % 7; ok(VARCMP_EQ == pVarBstrCmp(out, dayNames[day][fAbbrev], LOCALE_USER_DEFAULT, 0), "VarWeekdayName(%d,%d,%d): got wrong dayname: '%s'\n", iWeekday, fAbbrev, iFirstDay, buff); SysFreeString(out); } } } /* Cleanup */ for (day = 0; day <= 6; ++day) { for (fAbbrev = 0; fAbbrev <= 1; ++fAbbrev) { SysFreeString(dayNames[day][fAbbrev]); } } }
static void test_VarFormat(void) { static const WCHAR szTesting[] = { 't','e','s','t','i','n','g','\0' }; static const WCHAR szNum[] = { '3','9','6','9','7','.','1','1','\0' }; size_t i; WCHAR buffW[256]; char buff[256]; VARIANT in; VARIANT_BOOL bTrue = VARIANT_TRUE, bFalse = VARIANT_FALSE; int fd = 0, fw = 0; ULONG flags = 0; BSTR bstrin, out = NULL; HRESULT hres; CHECKPTR(VarFormat); if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH) { skip("Skipping VarFormat tests for non English language\n"); return; } GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char)); if (buff[0] != '.' || buff[1]) { skip("Skipping VarFormat tests as decimal separator is '%s'\n", buff); return; } GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, buff, sizeof(buff)/sizeof(char)); if (buff[0] != '2' || buff[1]) { skip("Skipping VarFormat tests as decimal places is '%s'\n", buff); return; } VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"True/False",S_OK,"True"); VARFMT(VT_BOOL,V_BOOL,VARIANT_FALSE,"True/False",S_OK,"False"); VNUMFMT(VT_I1,V_I1); VNUMFMT(VT_I2,V_I2); VNUMFMT(VT_I4,V_I4); if (has_i8) { VNUMFMT(VT_I8,V_I8); } VNUMFMT(VT_INT,V_INT); VNUMFMT(VT_UI1,V_UI1); VNUMFMT(VT_UI2,V_UI2); VNUMFMT(VT_UI4,V_UI4); if (has_i8) { VNUMFMT(VT_UI8,V_UI8); } VNUMFMT(VT_UINT,V_UINT); VNUMFMT(VT_R4,V_R4); VNUMFMT(VT_R8,V_R8); /* Reference types are dereferenced */ VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bTrue,"True/False",S_OK,"True"); VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bFalse,"True/False",S_OK,"False"); /* Dates */ for (i = 0; i < sizeof(VarFormat_date_results)/sizeof(FMTDATERES); i++) { if (i < 7) fd = i + 1; /* Test first day */ else fd = 0; VARFMT(VT_DATE,V_DATE,VarFormat_date_results[i].val, VarFormat_date_results[i].fmt,S_OK, VarFormat_date_results[i].res); } /* Named time formats */ GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, buff, sizeof(buff)/sizeof(char)); if (strcmp(buff, "h:mm:ss tt")) { skip("Skipping named time tests as time format is '%s'\n", buff); } else { for (i = 0; i < sizeof(VarFormat_namedtime_results)/sizeof(FMTDATERES); i++) { fd = 0; VARFMT(VT_DATE,V_DATE,VarFormat_namedtime_results[i].val, VarFormat_namedtime_results[i].fmt,S_OK, VarFormat_namedtime_results[i].res); } } /* Strings */ bstrin = SysAllocString(szTesting); VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x@\\x@",S_OK,"xtxesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x&\\x&",S_OK,"xtxesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x",S_OK,"txesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@@@@@@@@",S_OK," testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x@@@@@@@",S_OK," xtesting"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"!&&&&&&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&!",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,">&&",S_OK,"TESTING"); VARFMT(VT_BSTR,V_BSTR,bstrin,"<&&",S_OK,"testing"); VARFMT(VT_BSTR,V_BSTR,bstrin,"<&>&",S_OK,"testing"); SysFreeString(bstrin); bstrin = SysAllocString(szNum); todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"hh:mm",S_OK,"02:38"); todo_wine VARFMT(VT_BSTR,V_BSTR,bstrin,"mm-dd-yy",S_OK,"09-06-08"); SysFreeString(bstrin); /* Numeric values are converted to strings then output */ VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1"); /* Number formats */ VARFMT(VT_I4,V_I4,1,"#00000000",S_OK,"00000001"); VARFMT(VT_I4,V_I4,1,"000###",S_OK,"000001"); VARFMT(VT_I4,V_I4,1,"#00##00#0",S_OK,"00000001"); VARFMT(VT_I4,V_I4,1,"1#####0000",S_OK,"10001"); VARFMT(VT_I4,V_I4,1,"##abcdefghijklmnopqrstuvwxyz",S_OK,"1abcdefghijklmnopqrstuvwxyz"); VARFMT(VT_I4,V_I4,100000,"#,###,###,###",S_OK,"100,000"); VARFMT(VT_I4,V_I4,1,"0,000,000,000",S_OK,"0,000,000,001"); VARFMT(VT_I4,V_I4,123456789,"#,#.#",S_OK,"123,456,789."); VARFMT(VT_I4,V_I4,123456789,"###, ###, ###",S_OK,"123, 456, 789"); VARFMT(VT_I4,V_I4,1,"#;-#",S_OK,"1"); VARFMT(VT_I4,V_I4,-1,"#;-#",S_OK,"-1"); VARFMT(VT_R8,V_R8,1.23456789,"0#.0#0#0#0#0",S_OK,"01.234567890"); VARFMT(VT_R8,V_R8,1.2,"0#.0#0#0#0#0",S_OK,"01.200000000"); VARFMT(VT_R8,V_R8,9.87654321,"#0.#0#0#0#0#",S_OK,"9.87654321"); VARFMT(VT_R8,V_R8,9.8,"#0.#0#0#0#0#",S_OK,"9.80000000"); VARFMT(VT_R8,V_R8,0.00000008,"#0.#0#0#0#0#0",S_OK,"0.0000000800"); VARFMT(VT_R8,V_R8,0.00010705,"#0.##########",S_OK,"0.00010705"); VARFMT(VT_I4,V_I4,17,"#0",S_OK,"17"); VARFMT(VT_I4,V_I4,4711,"#0",S_OK,"4711"); VARFMT(VT_I4,V_I4,17,"#00",S_OK,"17"); VARFMT(VT_I4,V_I4,100,"0##",S_OK,"100"); VARFMT(VT_I4,V_I4,17,"#000",S_OK,"017"); VARFMT(VT_I4,V_I4,17,"#0.00",S_OK,"17.00"); VARFMT(VT_I4,V_I4,17,"#0000.00",S_OK,"0017.00"); VARFMT(VT_I4,V_I4,17,"#.00",S_OK,"17.00"); VARFMT(VT_R8,V_R8,1.7,"#.00",S_OK,"1.70"); VARFMT(VT_R8,V_R8,.17,"#.00",S_OK,".17"); VARFMT(VT_I4,V_I4,17,"#3",S_OK,"173"); VARFMT(VT_I4,V_I4,17,"#33",S_OK,"1733"); VARFMT(VT_I4,V_I4,17,"#3.33",S_OK,"173.33"); VARFMT(VT_I4,V_I4,17,"#3333.33",S_OK,"173333.33"); VARFMT(VT_I4,V_I4,17,"#.33",S_OK,"17.33"); VARFMT(VT_R8,V_R8,.17,"#.33",S_OK,".33"); VARFMT(VT_R8,V_R8,1.7,"0.0000E-000",S_OK,"1.7000E000"); VARFMT(VT_R8,V_R8,1.7,"0.0000e-1",S_OK,"1.7000e01"); VARFMT(VT_R8,V_R8,86.936849,"#0.000000000000e-000",S_OK,"86.936849000000e000"); VARFMT(VT_R8,V_R8,1.7,"#0",S_OK,"2"); VARFMT(VT_R8,V_R8,1.7,"#.33",S_OK,"2.33"); VARFMT(VT_R8,V_R8,1.7,"#3",S_OK,"23"); VARFMT(VT_R8,V_R8,1.73245,"0.0000E+000",S_OK,"1.7325E+000"); VARFMT(VT_R8,V_R8,9.9999999,"#0.000000",S_OK,"10.000000"); VARFMT(VT_R8,V_R8,1.7,"0.0000e+0#",S_OK,"1.7000e+0"); VARFMT(VT_R8,V_R8,100.0001e+0,"0.0000E+0",S_OK,"1.0000E+2"); VARFMT(VT_R8,V_R8,1000001,"0.0000e+1",S_OK,"1.0000e+61"); VARFMT(VT_R8,V_R8,100.0001e+25,"0.0000e+0",S_OK,"1.0000e+27"); VARFMT(VT_R8,V_R8,450.0001e+43,"#000.0000e+0",S_OK,"4500.0010e+42"); VARFMT(VT_R8,V_R8,0.0001e-11,"##00.0000e-0",S_OK,"1000.0000e-18"); VARFMT(VT_R8,V_R8,0.0317e-11,"0000.0000e-0",S_OK,"3170.0000e-16"); VARFMT(VT_R8,V_R8,0.0021e-11,"00##.0000e-0",S_OK,"2100.0000e-17"); VARFMT(VT_R8,V_R8,1.0001e-27,"##00.0000e-0",S_OK,"1000.1000e-30"); VARFMT(VT_R8,V_R8,47.11,".0000E+0",S_OK,".4711E+2"); VARFMT(VT_R8,V_R8,3.0401e-13,"#####.####e-0%",S_OK,"30401.e-15%"); VARFMT(VT_R8,V_R8,1.57,"0.00",S_OK,"1.57"); VARFMT(VT_R8,V_R8,-1.57,"0.00",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-1.57,"#.##",S_OK,"-1.57"); VARFMT(VT_R8,V_R8,-0.1,".#",S_OK,"-.1"); VARFMT(VT_R8,V_R8,0.099,"#.#",S_OK,".1"); VARFMT(VT_R8,V_R8,0.0999,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,0.099,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,0.0099,"#.##",S_OK,".01"); VARFMT(VT_R8,V_R8,0.0049,"#.##",S_OK,"."); VARFMT(VT_R8,V_R8,0.0094,"#.##",S_OK,".01"); VARFMT(VT_R8,V_R8,0.00099,"#.##",S_OK,"."); VARFMT(VT_R8,V_R8,0.0995,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,8.0995,"#.##",S_OK,"8.1"); VARFMT(VT_R8,V_R8,0.0994,"#.##",S_OK,".1"); VARFMT(VT_R8,V_R8,1.00,"#,##0.00",S_OK,"1.00"); VARFMT(VT_R8,V_R8,0.0995,"#.###",S_OK,".1"); /* 'out' is not cleared */ out = (BSTR)0x1; hres = pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */ ok(hres == S_OK, "got %08x\n", hres); SysFreeString(out); out = NULL; /* VT_NULL */ V_VT(&in) = VT_NULL; hres = pVarFormat(&in,NULL,fd,fw,0,&out); ok(hres == S_OK, "VarFormat failed with 0x%08x\n", hres); ok(out == NULL, "expected NULL formatted string\n"); /* Invalid args */ hres = pVarFormat(&in,NULL,fd,fw,flags,NULL); ok(hres == E_INVALIDARG, "Null out: expected E_INVALIDARG, got 0x%08x\n", hres); hres = pVarFormat(NULL,NULL,fd,fw,flags,&out); ok(hres == E_INVALIDARG, "Null in: expected E_INVALIDARG, got 0x%08x\n", hres); fd = -1; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fd = 8; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fd = 0; fw = -1; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); fw = 4; VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,""); }
int scan_glyph(TTF_Font *font, TTF_Glyph *glyph) { CHECKPTR(font); CHECKPTR(glyph); RETINIT(SUCCESS); if (!glyph->outline) { warn("failed to scan uninitialized glyph outline"); return FAILURE; } else if (glyph->outline->point < 0) { warn("failed to scan unscaled glyph outline"); return FAILURE; } else if (glyph->number_of_contours == 0) { /* Zero-length glyph with no outline. */ return SUCCESS; } TTF_Outline *outline = glyph->outline; TTF_Bitmap *bitmap = NULL; uint32_t bg, fg; if (font->raster_flags & RENDER_FPAA) { /* Anti-aliased rendering - oversample outline then downsample. */ bg = 0xFFFFFF; fg = 0x000000; if (!glyph->bitmap) { glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 2, (outline->y_max - outline->y_min) / 2, bg); } /* Intermediate oversampled bitmap. */ bitmap = create_bitmap(outline->x_max - outline->x_min, outline->y_max - outline->y_min, bg); } else if (font->raster_flags & RENDER_ASPAA) { /* Sub-pixel rendering - oversample in x-direction then downsample. */ bg = 0xFFFFFF; fg = 0x000000; if (!glyph->bitmap) { glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 3, outline->y_max - outline->y_min, bg); } /* Intermediate oversampled bitmap. */ bitmap = create_bitmap(outline->x_max - outline->x_min, outline->y_max - outline->y_min, bg); } else { /* Normal rendering - write directly to glyph bitmap. */ bg = 0xFFFFFF; fg = 0x000000; if (!glyph->bitmap) { glyph->bitmap = create_bitmap(outline->x_max - outline->x_min, outline->y_max - outline->y_min, bg); } bitmap = glyph->bitmap; } /* Create a scan-line for each row in the scaled outline. */ int num_scanlines = outline->y_max - outline->y_min; TTF_Scan_Line *scanlines = malloc(num_scanlines * sizeof(*scanlines)); CHECKFAIL(scanlines, warnerr("failed to alloc glyph scan lines")); /* Find intersections of each scan-line with contour segments. */ for (int i = 0; i < num_scanlines; i++) { TTF_Scan_Line *scanline = &scanlines[i]; init_scanline(scanline, outline->num_contours * 2); scanline->y = outline->y_max - i; for (int j = 0; j < outline->num_contours; j++) { TTF_Contour *contour = &outline->contours[j]; int k; for (k = 0; k < contour->num_segments; k++) { TTF_Segment *segment = &contour->segments[k]; intersect_segment(segment, scanline); } } /* Round pixel intersection values to 1/64 of a pixel. */ for (int j = 0; j < scanline->num_intersections; j++) { scanline->x[j] = round_pixel(scanline->x[j]); } /* Sort intersections from left to right. */ qsort(scanline->x, scanline->num_intersections, sizeof(*scanline->x), cmp_intersections); // printf("Intersections: "); // char *sep = ""; // for (int j = 0; j < scanline->num_intersections; j++) { // printf("%s%f", sep, scanline->x[j]); // sep = ", "; // } // printf("\n"); int int_index = 0, fill = 0; for (int j = 0; j < bitmap->w; j++) { if (int_index < scanline->num_intersections) { if ((outline->x_min + j) >= scanline->x[int_index]) { fill = !fill; /* Skip over duplicate intersections. */ int k; for (k = 1; int_index+k < scanline->num_intersections; k++) { if (scanline->x[int_index] != scanline->x[int_index+k]) { break; } } int_index += k; } } if (fill) { bitmap_set(bitmap, j, i, fg); } } } if (font->raster_flags & RENDER_FPAA) { /* Downsample intermediate bitmap. */ for (int y = 0; y < glyph->bitmap->h; y++) { for (int x = 0; x < glyph->bitmap->w; x++) { /* Calculate pixel coverage: * coverage = number filled samples / number samples */ float coverage = 0; if (bitmap_get(bitmap, (2*x), (2*y)) == 0x000000) coverage++; if (bitmap_get(bitmap, (2*x)+1, (2*y)) == 0x000000) coverage++; if (bitmap_get(bitmap, (2*x), (2*y)+1) == 0x000000) coverage++; if (bitmap_get(bitmap, (2*x)+1, (2*y)+1) == 0x000000) coverage++; coverage /= 4; uint8_t shade = 0xFF*(1-coverage); uint32_t pixel = (shade << 16) | (shade << 8) | (shade << 0); bitmap_set(glyph->bitmap, x, y, pixel); } } free_bitmap(bitmap); } else if (font->raster_flags & RENDER_ASPAA) { /* Perform five element low-pass filter. */ TTF_Bitmap *temp = create_bitmap(bitmap->w, bitmap->h, bg); for (int y = 0; y < bitmap->h; y++) { for (int x = 0; x < bitmap->w; x++) { uint32_t pixel = 0x000000; pixel += bitmap_get(bitmap, x-2, y) * (1.0 / 9.0); pixel += bitmap_get(bitmap, x-1, y) * (2.0 / 9.0); pixel += bitmap_get(bitmap, x, y) * (3.0 / 9.0); pixel += bitmap_get(bitmap, x+1, y) * (2.0 / 9.0); pixel += bitmap_get(bitmap, x+2, y) * (1.0 / 9.0); bitmap_set(temp, x, y, pixel); } } free_bitmap(bitmap); bitmap = temp; /* Downsample intermediate bitmap. */ for (int y = 0; y < glyph->bitmap->h; y++) { for (int x = 0; x < glyph->bitmap->w; x++) { uint8_t r, g, b; r = (bitmap_get(bitmap, (3*x), y) * 0xFF) / 0xFFFFFF; g = (bitmap_get(bitmap, (3*x)+1, y) * 0xFF) / 0xFFFFFF; b = (bitmap_get(bitmap, (3*x)+2, y) * 0xFF) / 0xFFFFFF; uint32_t pixel = (r << 16) | (g << 8) | (b << 0); bitmap_set(glyph->bitmap, x, y, pixel); } } free_bitmap(bitmap); } RETRELEASE(free_scanlines(scanlines, num_scanlines)); }