/** *cairo_status_to_string: *@status:acairostatus * *Providesahuman-readabledescriptionofa#cairo_status_t. * *Returns:astringrepresentationofthestatus * *Since:1.0
**/ constchar *
cairo_status_to_string (cairo_status_t status)
{ switch (status) { case CAIRO_STATUS_SUCCESS: return"no error has occurred"; case CAIRO_STATUS_NO_MEMORY: return"out of memory"; case CAIRO_STATUS_INVALID_RESTORE: return"cairo_restore() without matching cairo_save()"; case CAIRO_STATUS_INVALID_POP_GROUP: return"no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()"; case CAIRO_STATUS_NO_CURRENT_POINT: return"no current point defined"; case CAIRO_STATUS_INVALID_MATRIX: return"invalid matrix (not invertible)"; case CAIRO_STATUS_INVALID_STATUS: return"invalid value for an input cairo_status_t"; case CAIRO_STATUS_NULL_POINTER: return"NULL pointer"; case CAIRO_STATUS_INVALID_STRING: return"input string not valid UTF-8"; case CAIRO_STATUS_INVALID_PATH_DATA: return"input path data not valid"; case CAIRO_STATUS_READ_ERROR: return"error while reading from input stream"; case CAIRO_STATUS_WRITE_ERROR: return"error while writing to output stream"; case CAIRO_STATUS_SURFACE_FINISHED: return"the target surface has been finished"; case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: return"the surface type is not appropriate for the operation"; case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: return"the pattern type is not appropriate for the operation"; case CAIRO_STATUS_INVALID_CONTENT: return"invalid value for an input cairo_content_t"; case CAIRO_STATUS_INVALID_FORMAT: return"invalid value for an input cairo_format_t"; case CAIRO_STATUS_INVALID_VISUAL: return"invalid value for an input Visual*"; case CAIRO_STATUS_FILE_NOT_FOUND: return"file not found"; case CAIRO_STATUS_INVALID_DASH: return"invalid value for a dash setting"; case CAIRO_STATUS_INVALID_DSC_COMMENT: return"invalid value for a DSC comment"; case CAIRO_STATUS_INVALID_INDEX: return"invalid index passed to getter"; case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: return"clip region not representable in desired format"; case CAIRO_STATUS_TEMP_FILE_ERROR: return"error creating or writing to a temporary file"; case CAIRO_STATUS_INVALID_STRIDE: return"invalid value for stride"; case CAIRO_STATUS_FONT_TYPE_MISMATCH: return"the font type is not appropriate for the operation"; case CAIRO_STATUS_USER_FONT_IMMUTABLE: return"the user-font is immutable"; case CAIRO_STATUS_USER_FONT_ERROR: return"error occurred in a user-font callback function"; case CAIRO_STATUS_NEGATIVE_COUNT: return"negative number used where it is not allowed"; case CAIRO_STATUS_INVALID_CLUSTERS: return"input clusters do not represent the accompanying text and glyph arrays"; case CAIRO_STATUS_INVALID_SLANT: return"invalid value for an input cairo_font_slant_t"; case CAIRO_STATUS_INVALID_WEIGHT: return"invalid value for an input cairo_font_weight_t"; case CAIRO_STATUS_INVALID_SIZE: return"invalid value (typically too big) for the size of the input (surface, pattern, etc.)"; case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: return"user-font method not implemented"; case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: return"the device type is not appropriate for the operation"; case CAIRO_STATUS_DEVICE_ERROR: return"an operation to the device caused an unspecified error"; case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: return"invalid operation during mesh pattern construction"; case CAIRO_STATUS_DEVICE_FINISHED: return"the target device has been finished"; case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: return"CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID used but no CAIRO_MIME_TYPE_JBIG2_GLOBAL data provided"; case CAIRO_STATUS_PNG_ERROR: return"error occurred in libpng while reading from or writing to a PNG file"; case CAIRO_STATUS_FREETYPE_ERROR: return"error occurred in libfreetype"; case CAIRO_STATUS_WIN32_GDI_ERROR: return"error occurred in the Windows Graphics Device Interface"; case CAIRO_STATUS_TAG_ERROR: return"invalid tag name, attributes, or nesting"; case CAIRO_STATUS_DWRITE_ERROR: return"Window Direct Write error"; case CAIRO_STATUS_SVG_FONT_ERROR: return"error occured while rendering an OpenType-SVG font"; default: case CAIRO_STATUS_LAST_STATUS: return"<unknown error status>";
}
}
for (i = 0; i < num_clusters; i++) { int cluster_bytes = clusters[i].num_bytes; int cluster_glyphs = clusters[i].num_glyphs;
if (cluster_bytes < 0 || cluster_glyphs < 0) goto BAD;
/* A cluster should cover at least one character or glyph. *Ican'tseeanyusefora0,0cluster. *Ican'tseeanimmediateuseforazero-textcluster *rightnoweither,buttheydon'tharm. *Zero-glyphclustersontheotherhandareusefulfor
* things like U+200C ZERO WIDTH NON-JOINER */ if (cluster_bytes == 0 && cluster_glyphs == 0) goto BAD;
/* Since n_bytes and n_glyphs are unsigned, but the rest of
* values involved are signed, we can detect overflow easily */ if (n_bytes+cluster_bytes > (unsignedint)utf8_len || n_glyphs+cluster_glyphs > (unsignedint)num_glyphs) goto BAD;
/* Make sure we've got valid UTF-8 for the cluster */
status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL); if (unlikely (status)) return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS);
/** *_cairo_operator_bounded_by_mask: *@op:a#cairo_operator_t * *Aboundedoperatorisonewheremaskpixel *ofzeroresultsinnoeffectonthedestinationimage. * *Unboundedoperatorsoftenrequirespecialhandling;ifyou,for *example,drawtrapezoidswithanunboundedoperator,theeffect *extendspasttheboundingboxofthetrapezoids. * *Returnvalue:%TRUEiftheoperatorisboundedbythemaskoperand
**/
cairo_bool_t
_cairo_operator_bounded_by_mask (cairo_operator_t op)
{ switch (op) { case CAIRO_OPERATOR_CLEAR: case CAIRO_OPERATOR_SOURCE: case CAIRO_OPERATOR_OVER: case CAIRO_OPERATOR_ATOP: case CAIRO_OPERATOR_DEST: case CAIRO_OPERATOR_DEST_OVER: case CAIRO_OPERATOR_DEST_OUT: case CAIRO_OPERATOR_XOR: case CAIRO_OPERATOR_ADD: case CAIRO_OPERATOR_SATURATE: case CAIRO_OPERATOR_MULTIPLY: case CAIRO_OPERATOR_SCREEN: case CAIRO_OPERATOR_OVERLAY: case CAIRO_OPERATOR_DARKEN: case CAIRO_OPERATOR_LIGHTEN: case CAIRO_OPERATOR_COLOR_DODGE: case CAIRO_OPERATOR_COLOR_BURN: case CAIRO_OPERATOR_HARD_LIGHT: case CAIRO_OPERATOR_SOFT_LIGHT: case CAIRO_OPERATOR_DIFFERENCE: case CAIRO_OPERATOR_EXCLUSION: case CAIRO_OPERATOR_HSL_HUE: case CAIRO_OPERATOR_HSL_SATURATION: case CAIRO_OPERATOR_HSL_COLOR: case CAIRO_OPERATOR_HSL_LUMINOSITY: return TRUE; case CAIRO_OPERATOR_OUT: case CAIRO_OPERATOR_IN: case CAIRO_OPERATOR_DEST_IN: case CAIRO_OPERATOR_DEST_ATOP: returnFALSE; default:
ASSERT_NOT_REACHED; returnFALSE; /* squelch warning */
}
}
/** *_cairo_operator_bounded_by_source: *@op:a#cairo_operator_t * *Aboundedoperatorisonewheresourcepixelsofzero *(inallfourcomponents,r,g,banda)effectnochange *intheresultingdestinationimage. * *Unboundedoperatorsoftenrequirespecialhandling;ifyou,for *example,copyasurfacewiththeSOURCEoperator,theeffect *extendspasttheboundingboxofthesourcesurface. * *Returnvalue:%TRUEiftheoperatorisboundedbythesourceoperand
**/
cairo_bool_t
_cairo_operator_bounded_by_source (cairo_operator_t op)
{ switch (op) { case CAIRO_OPERATOR_OVER: case CAIRO_OPERATOR_ATOP: case CAIRO_OPERATOR_DEST: case CAIRO_OPERATOR_DEST_OVER: case CAIRO_OPERATOR_DEST_OUT: case CAIRO_OPERATOR_XOR: case CAIRO_OPERATOR_ADD: case CAIRO_OPERATOR_SATURATE: case CAIRO_OPERATOR_MULTIPLY: case CAIRO_OPERATOR_SCREEN: case CAIRO_OPERATOR_OVERLAY: case CAIRO_OPERATOR_DARKEN: case CAIRO_OPERATOR_LIGHTEN: case CAIRO_OPERATOR_COLOR_DODGE: case CAIRO_OPERATOR_COLOR_BURN: case CAIRO_OPERATOR_HARD_LIGHT: case CAIRO_OPERATOR_SOFT_LIGHT: case CAIRO_OPERATOR_DIFFERENCE: case CAIRO_OPERATOR_EXCLUSION: case CAIRO_OPERATOR_HSL_HUE: case CAIRO_OPERATOR_HSL_SATURATION: case CAIRO_OPERATOR_HSL_COLOR: case CAIRO_OPERATOR_HSL_LUMINOSITY: return TRUE; case CAIRO_OPERATOR_CLEAR: case CAIRO_OPERATOR_SOURCE: case CAIRO_OPERATOR_OUT: case CAIRO_OPERATOR_IN: case CAIRO_OPERATOR_DEST_IN: case CAIRO_OPERATOR_DEST_ATOP: returnFALSE; default:
ASSERT_NOT_REACHED; returnFALSE; /* squelch warning */
}
}
uint32_t
_cairo_operator_bounded_by_either (cairo_operator_t op)
{ switch (op) { case CAIRO_OPERATOR_OVER: case CAIRO_OPERATOR_ATOP: case CAIRO_OPERATOR_DEST: case CAIRO_OPERATOR_DEST_OVER: case CAIRO_OPERATOR_DEST_OUT: case CAIRO_OPERATOR_XOR: case CAIRO_OPERATOR_ADD: case CAIRO_OPERATOR_SATURATE: case CAIRO_OPERATOR_MULTIPLY: case CAIRO_OPERATOR_SCREEN: case CAIRO_OPERATOR_OVERLAY: case CAIRO_OPERATOR_DARKEN: case CAIRO_OPERATOR_LIGHTEN: case CAIRO_OPERATOR_COLOR_DODGE: case CAIRO_OPERATOR_COLOR_BURN: case CAIRO_OPERATOR_HARD_LIGHT: case CAIRO_OPERATOR_SOFT_LIGHT: case CAIRO_OPERATOR_DIFFERENCE: case CAIRO_OPERATOR_EXCLUSION: case CAIRO_OPERATOR_HSL_HUE: case CAIRO_OPERATOR_HSL_SATURATION: case CAIRO_OPERATOR_HSL_COLOR: case CAIRO_OPERATOR_HSL_LUMINOSITY: return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE; case CAIRO_OPERATOR_CLEAR: case CAIRO_OPERATOR_SOURCE: return CAIRO_OPERATOR_BOUND_BY_MASK; case CAIRO_OPERATOR_OUT: case CAIRO_OPERATOR_IN: case CAIRO_OPERATOR_DEST_IN: case CAIRO_OPERATOR_DEST_ATOP: return0; default:
ASSERT_NOT_REACHED; returnFALSE; /* squelch warning */
}
}
#if DISABLE_SOME_FLOATING_POINT /* This function is identical to the C99 function lround(), except that it *performsarithmeticrounding(floor(d+.5)insteadofaway-from-zerorounding)and *hasavalidinputrangeof(INT_MIN,INT_MAX]insteadof *[INT_MIN,INT_MAX].Itismuchfasteronbothx86andFPU-lesssystems *thanothercommonlyusedmethodsforrounding(lround,round,rint,lrint *orfloat(d+0.5)). * *Thereasonwhythisfunctionismuchfasteronx86thanother *methodsisduetothefactthatitavoidsthefldcwinstruction. *ThisinstructionincursalargeperformancepenaltyonmodernIntel *processorsduetohowitpreventsefficientinstructionpipelining. * *ThereasonwhythisfunctionismuchfasteronFPU-lesssystemsisfor *anentirelydifferentreason.Allcommonroundingmethodsinvolvemultiple *floating-pointoperations.Eachoneoftheseoperationshastobe *emulatedinsoftware,whichaddsuptobealargeperformancepenalty. *Thisfunctiondoesn'tperformanyfloating-pointcalculations,andthus *avoidsthispenalty.
*/ int
_cairo_lround (double d)
{
uint32_t top, shift_amount, output; union { double d;
uint64_t ui64;
uint32_t ui32[2];
} u;
u.d = d;
/* If the integer word order doesn't match the float word order, we swap *thewordsoftheinputdouble.Thisisneededbecausewewillbe *treatingthewholedoubleasa64-bitunsignedinteger.Noticethatwe *useWORDS_BIGENDIANtodetecttheintegerwordorder,whichisn't *exactlycorrectbecauseWORDS_BIGENDIANreferstobyteorder,notword *order.Thus,wearemakingtheassumptionthatthebyteorderisthe *sameastheintegerwordorderwhich,onthemodernmachinesthatwe *careabout,isOK.
*/ #if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \
(!defined(FLOAT_WORDS_BIGENDIAN) && defined(WORDS_BIGENDIAN))
{
uint32_t temp = u.ui32[0];
u.ui32[0] = u.ui32[1];
u.ui32[1] = temp;
} #endif
#ifdef WORDS_BIGENDIAN #define MSW (0) /* Most Significant Word */ #define LSW (1) /* Least Significant Word */ #else #define MSW (1) #define LSW (0) #endif
/* By shifting the most significant word of the input double to the *right20places,wegetthevery"top"ofthedoublewheretheexponent *andsignbitlie.
*/
top = u.ui32[MSW] >> 20;
/* Here, we calculate how much we have to shift the mantissa to normalize *ittoanintegervalue.Weextracttheexponent"top"bymaskingoutthe *signbit,thenwecalculatetheshiftamountbysubtractingtheexponent *fromthebias.Noticethatthecorrectbiasfor64-bitdoublesis *actually1075,butweuse1053insteadfortworeasons: * *1)Toperformroundinglateron,wewillfirstneedthetarget *valueina31.1fixed-pointformat.Thus,thebiasneedstobeone *less:(1075-1:1074). * *2)Toavoidshiftingthemantissaasafull64-bitinteger(whichis *costlyoncertainarchitectures),webreaktheshiftintotwoparts. *First,theupperandlowerpartsofthemantissaareshifted *individuallybyaconstantamountthatallvalidinputswillrequire *attheveryleast.Thisamountischosentobe21,becausethiswill *allowthetwopartsofthemantissatolaterbecombinedintoa *single32-bitrepresentation,onwhichtheremainderoftheshift *willbeperformed.Thus,wedecreasethebiasbyanadditional21: *(1074-21:1053).
*/
shift_amount = 1053 - (top & 0x7FF);
/* We are done with the exponent portion in "top", so here we shift it off *theend.
*/
top >>= 11;
/* Before we perform any operations on the mantissa, we need to OR in *theimplicit1atthetop(seetheIEEE-754spec).Weneedn'tmask *offthesignbitnortheexponentbitsbecausethesehigherbitswon't *makeabitofdifferenceintherestofourcalculations.
*/
u.ui32[MSW] |= 0x100000;
/* If the input double is negative, we have to decrease the mantissa *byahair.Thisisanimportantpartofperformingarithmeticrounding, *asnegativenumbersmustroundtowardspositiveinfinityinthe *halfwasecaseof-x.5.Since"top"containsonlythesignbitatthis *point,wecanjustdecreasethemantissabythevalueof"top".
*/
u.ui64 -= top;
/* By decrementing "top", we create a bitmask with a value of either *0x0(iftheinputwasnegative)or0xFFFFFFFF(iftheinputwaspositive *andthustheunsignedsubtractionunderflowed)thatwe'lluselater.
*/
top--;
/* Here, we shift the mantissa by the constant value as described above. *Wecanemulatea64-bitshiftrightby21throughshiftingthetop32 *bitsleft11placesandORinginthebottom32bitsshifted21places *totheright.Bothpartsofthemantissaarenowpackedintoasingle *32-bitinteger.Althoughweseverelytruncatethelowerpartinthe *process,westillhaveenoughsignificantbitstoperformtheconversion *withouterror(forallvalidinputs).
*/
output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21);
/* Next, we perform the shift that converts the X.Y fixed-point number *currentlyfoundin"output"tothedesired31.1fixed-pointformat *neededforthefollowingroundingstep.Itisimportanttoconsider *allpossiblevaluesfor"shift_amount"atthispoint: * *-{shift_amount<0}Sinceshift_amountisanunsignedinteger,it *reallycan'thaveavaluelessthanzero.But,iftheshift_amount *calculationabovecausedunderflow(whichwouldhappenwith *input>INT_MAXorinput<=INT_MIN)thenshift_amountwillnowbe *averylargenumber,andsothisshiftwillresultincomplete *garbage.Butthat'sOK,astheinputwasoutofourrange,soour *outputisundefined. * *-{shift_amount>31}Ifthemagnitudeoftheinputwasverysmall *(i.e.|input|<<1.0),shift_amountwillhaveavaluegreaterthan *31.Thus,thisshiftwillalsoresultingarbage.Afterperforming *theshift,wewillzero-out"output"ifthisisthecase. * *-{0<=shift_amount<32}Inthiscase,theshiftwillproperlyconvert *themantissaintoa31.1fixed-pointnumber.
*/
output >>= shift_amount;
/* This is where we perform rounding with the 31.1 fixed-point number. *Sincewhatwe'reafterisarithmeticrounding,wesimplyaddthesingle *fractionalbitintotheintegerpartof"output",andjustkeepthe *integerpart.
*/
output = (output >> 1) + (output & 1);
/* Here, we zero-out the result if the magnitude if the input was very small *(asexplainedinthesectionabove).Noticethatallinputoutofthe *validrangeisalsocaughtbythiscondition,whichmeansweproduce0 *forallinvalidinput,whichisanicesideeffect. * *Themoststraightforwardwaytodothiswouldbe: * *if(shift_amount>31) *output=0; * *Butwecanusealittletricktoavoidthepotentialbranch.The *expression(shift_amount>31)willbeeither1or0,whichwhen *decrementedwillbeeither0x0or0xFFFFFFFF(unsignedunderflow), *whichcanbeusedtoconditionallymaskawayallthebitsin"output" *(inthe0x0case),effectivelyzeroingitout.Certain,compilerswould *havedonethisforusautomatically.
*/
output &= ((shift_amount > 31) - 1);
/* If the input double was a negative number, then we have to negate our *output.Themoststraightforwardwaytodothiswouldbe: * *if(!top) *output=-output; * *as"top"atthispointiseither0x0(iftheinputwasnegative)or *0xFFFFFFFF(iftheinputwaspositive).But,wecanuseatrickto *avoidthebranch.Observethatthefollowingsnippetofcodehasthe *sameeffectasthereferencesnippetabove: * *if(!top) *output=0-output; *else *output=output-0; * *Armedwiththebitmaskfoundin"top",wecancondensethetwostatements *intothefollowing: * *output=(output&top)-(output&~top); * *where,inthecasethattheinputdoublewasnegative,"top"willbe0, *andthestatementwillbeequivalentto: * *output=(0)-(output); * *andiftheinputdoublewaspositive,"top"willbe0xFFFFFFFF,andthe *statementwillbeequivalentto: * *output=(output)-(0); * *Which,aspointedoutearlier,isequivalenttotheoriginalreference *snippet.
*/
output = (output & top) - (output & ~top);
return output; #undef MSW #undef LSW
} #endif
/* Convert a 32-bit IEEE single precision floating point number to a *'half'representation(s10.5)
*/
uint16_t
_cairo_half_from_float (float f)
{ union {
uint32_t ui; float f;
} u; int s, e, m;
u.f = f;
s = (u.ui >> 16) & 0x00008000;
e = ((u.ui >> 23) & 0x000000ff) - (127 - 15);
m = u.ui & 0x007fffff; if (e <= 0) { if (e < -10) { /* underflow */ return0;
}
m = (m | 0x00800000) >> (1 - e);
/* round to nearest, round 0.5 up. */ if (m & 0x00001000)
m += 0x00002000; return s | (m >> 13);
} elseif (e == 0xff - (127 - 15)) { if (m == 0) { /* infinity */ return s | 0x7c00;
} else { /* nan */
m >>= 13; return s | 0x7c00 | m | (m == 0);
}
} else { /* round to nearest, round 0.5 up. */ if (m & 0x00001000) {
m += 0x00002000;
if (m & 0x00800000) {
m = 0;
e += 1;
}
}
if (e > 30) { /* overflow -> infinity */ return s | 0x7c00;
}
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7) /* Glibc 2.7 supports the "e" mode flag that opens the file with O_CLOEXEC.
* this avoid the race condition in the fcntl fallback below. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.