void EEL_Editor::draw_string_urlchk(int *ml, int *skipcnt, const char *str, int amt, int *attr, int newAttr) { if (amt > 0 && (newAttr == SYNTAX_COMMENT || newAttr == SYNTAX_STRING)) { const char *sstr=str; while (amt > 0 && *str) { const char *str_scan = str; int l=0; while (l < 10 && *str_scan) { str_scan += l; l=0; while (*str_scan && (strncmp(str_scan,"http://",7) || (sstr != str_scan && isalnum(str_scan[-1]))) && str_scan < str+amt) str_scan++; if (!*str_scan || str_scan >= str+amt) break; while (str_scan[l] && str_scan[l] != ')' && str_scan[l] != '\"' && str_scan[l] != ')' && str_scan[l] != ' ' && str_scan[l] != '\t') l++; } if (!*str_scan || str_scan >= str+amt) break; // allow default processing to happen if we reached the end of the string if (l > amt) l=amt; if (str_scan > str) { const int sz=wdl_min(str_scan-str,amt); draw_string_internal(ml,skipcnt,str,sz,attr,newAttr); str += sz; amt -= sz; } const int sz=wdl_min(l,amt); if (sz>0) { draw_string_internal(ml,skipcnt,str,sz,attr,SYNTAX_HIGHLIGHT1); str += sz; amt -= sz; } } } draw_string_internal(ml,skipcnt,str,amt,attr,newAttr); }
char *projectcontext_fastDoubleToString(double value, char *bufOut, int prec_digits) { value = denormal_filter_double2(value); if (value<0.0) { value=-value; *bufOut++ = '-'; } if (value > 2147483647.0) { if (value >= 1.0e40) sprintf(bufOut, "%e", value); else sprintf(bufOut, "%.*f", wdl_min(prec_digits,8), value); while (*bufOut) bufOut++; return bufOut; } unsigned int value_i, frac, frac2; int prec_digits2 = 0; if (prec_digits>0) { static const unsigned int scales[9] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; value_i = (unsigned int)value; const int value_digits = value_i >= 10000 ? ( value_i >= 1000000 ? (value_i >= 100000000 ? (value_i >= 1000000000 ? 10 : 9) : (value_i >= 10000000 ? 8 : 7)) : (value_i >= 100000 ? 6 : 5) ) : ( value_i >= 100 ? (value_i >= 1000 ? 4 : 3) : (value_i >= 10 ? 2 : 1) ); // double precision is limited to about 17 decimal digits of meaningful values if (prec_digits + value_digits > 17) prec_digits = 17-value_digits; if (prec_digits > 9) { prec_digits2 = prec_digits - 9; prec_digits = 9; if (prec_digits2 > 9) prec_digits2 = 9; } const unsigned int prec_scale = scales[prec_digits-1]; const double dfrac = (value - value_i) * prec_scale; if (prec_digits2 > 0) { const unsigned int prec_scale2 = scales[prec_digits2-1]; frac = (unsigned int) dfrac; double dfrac2 = (dfrac - frac) * prec_scale2; frac2 = (unsigned int) (dfrac2 + 0.5); const int prec_scale2_small = wdl_min(prec_scale2/1024,10); if (frac2 <= prec_scale2_small) frac2=0; else if (frac2 >= prec_scale2 - prec_scale2_small - 1) frac2=prec_scale2; if (frac2 >= prec_scale2) { frac2 -= prec_scale2; frac++; } } else { frac = (unsigned int) (dfrac + 0.5); frac2 = 0; const int prec_scale_small = wdl_min(prec_scale/1024,10); if (frac <= prec_scale_small) frac=0; else if (frac>=prec_scale-prec_scale_small - 1) frac=prec_scale; } if (frac >= prec_scale) // round up to next integer { frac -= prec_scale; value_i++; } } else // round to int { value_i = (unsigned int)(value+0.5); frac2 = frac = 0; } char digs[32]; if (value_i) { int tmp=value_i; int x = 0; do { const int a = (tmp%10); tmp/=10; digs[x++]='0' + a; } while (tmp); while (x>0) *bufOut++ = digs[--x]; } else { *bufOut++ = '0'; } if (frac || frac2) { int x = 0; int tmp=frac; int dleft = prec_digits; *bufOut++='.'; if (frac) do { const int a = (tmp%10); tmp /= 10; if (x || a || frac2) digs[x++] = '0'+a; } while (dleft-- > 0 && tmp); while (dleft-->0) *bufOut++ = '0'; while (x>0) *bufOut++ = digs[--x]; // x is 0 if (frac2) { tmp=frac2; dleft = prec_digits2; do { const int a = (tmp%10); tmp /= 10; if (x || a) digs[x++] = '0'+a; } while (dleft-- > 0 && tmp); while (dleft-->0) *bufOut++ = '0'; while (x>0) *bufOut++ = digs[--x]; } } *bufOut = 0; return bufOut; }
int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align) { const char *obuf=buf; HDC__ *ct=(HDC__ *)ctx; if (!r) return 0; int lineh = 8; int charw = 8; HGDIOBJ__ *font = NULL; #ifdef SWELL_FREETYPE int ascent=0; font = HDC_VALID(ct) && HGDIOBJ_VALID(ct->curfont,TYPE_FONT) ? ct->curfont : SWELL_GetDefaultFont(); FT_Face face = NULL; if (font && font->fontface) { face=(FT_Face)font->fontface; lineh = face->size->metrics.height/64; ascent = face->size->metrics.ascender/64; charw = face->size->metrics.max_advance/64; } #endif if (align&DT_CALCRECT) { if (!font && (align&DT_SINGLELINE)) { r->right = r->left + ( buflen < 0 ? strlen(buf) : buflen ) * charw; int h = r->right ? lineh:0; r->bottom = r->top+h; return h; } int xpos=0; int ypos=0; r->bottom=r->top; bool in_prefix=false; while (buflen && *buf) // if buflen<0, go forever { unsigned short c=0; int charlen = utf8char(buf,&c); buf+=charlen; if (buflen > 0) { buflen -= charlen; if (buflen < 0) buflen=0; } if (!c) break; if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) { in_prefix = true; continue; } in_prefix=false; if (c == '\n') { ypos += lineh; xpos=0; } else if (c != '\r') { if (font) { #ifdef SWELL_FREETYPE if (!FT_Load_Char(face, c, FT_LOAD_DEFAULT) && face->glyph) { // measure character FT_GlyphSlot g = face->glyph; int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; if (r->left+rext > r->right) r->right = r->left+rext; xpos += g->metrics.horiAdvance/64; int bext = r->top + ypos + lineh; // ascent + (g->metrics.height - g->metrics.horiBearingY)/64; if (bext > r->bottom) r->bottom = bext; continue; } } #endif xpos += c=='\t' ? charw*5 : charw; if (r->top + ypos + lineh > r->bottom) r->bottom = r->top+ypos+lineh; if (r->left+xpos>r->right) r->right=r->left+xpos; } } return r->bottom-r->top; } if (!HDC_VALID(ct)) return 0; RECT use_r = *r; use_r.left += ct->surface_offs.x; use_r.right += ct->surface_offs.x; use_r.top += ct->surface_offs.y; use_r.bottom += ct->surface_offs.y; int xpos = use_r.left; int ypos = use_r.top; if (align&(DT_CENTER|DT_VCENTER|DT_RIGHT|DT_BOTTOM)) { RECT tr={0,}; DrawText(ctx,buf,buflen,&tr,align|DT_CALCRECT); if (align&DT_CENTER) xpos -= ((tr.right-tr.left) - (use_r.right-use_r.left))/2; else if (align&DT_RIGHT) xpos = use_r.right - (tr.right-tr.left); if (align&DT_VCENTER) ypos -= ((tr.bottom-tr.top) - (use_r.bottom-use_r.top))/2; else if (align&DT_BOTTOM) ypos = use_r.bottom - (tr.bottom-tr.top); } LICE_IBitmap *surface = ct->surface; int fgcol = ct->cur_text_color_int; int bgcol = ct->curbkcol; int bgmode = ct->curbkmode; int clip_x1=wdl_max(use_r.left,0), clip_y1 = wdl_max(use_r.top,0); int clip_w=0, clip_h=0; if (surface) { clip_w = wdl_min(use_r.right,surface->getWidth())-clip_x1; clip_h = wdl_min(use_r.bottom,surface->getHeight())-clip_y1; if (clip_w<0)clip_w=0; if (clip_h<0)clip_h=0; } LICE_SubBitmap clipbm(surface,clip_x1,clip_y1,clip_w,clip_h); if (surface && !(align&DT_NOCLIP)) { surface = &clipbm; xpos-=clip_x1; ypos-=clip_y1; } int left_xpos = xpos,ysize=0,max_xpos=0; int start_ypos = ypos; bool in_prefix=false; while (buflen && *buf) { unsigned short c=0; int charlen = utf8char(buf,&c); if (buflen>0) { buflen -= charlen; if (buflen<0) buflen=0; } buf+=charlen; bool doUl=in_prefix; if (c=='&' && !in_prefix && !(align&DT_NOPREFIX)) { in_prefix = true; continue; } in_prefix=false; if (c=='\n' && !(align&DT_SINGLELINE)) { xpos=left_xpos; ypos+=lineh; } else if (c=='\r') {} else { bool needr=true; if (font) { #ifdef SWELL_FREETYPE if (!FT_Load_Char(face, c, FT_LOAD_RENDER) && face->glyph) { FT_GlyphSlot g = face->glyph; if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,g->metrics.horiAdvance/64,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); LICE_DrawGlyphEx(surface,xpos+g->bitmap_left,ypos+ascent-g->bitmap_top,fgcol,(LICE_pixel_chan *)g->bitmap.buffer,g->bitmap.width,g->bitmap.pitch,g->bitmap.rows,1.0f,LICE_BLIT_MODE_COPY); int rext = xpos + (g->metrics.width + g->metrics.horiBearingX)/64; if (rext<=xpos) rext=xpos + g->metrics.horiAdvance/64; if (rext > max_xpos) max_xpos=rext; xpos += g->metrics.horiAdvance/64; int bext = ypos + lineh; // + (g->metrics.height - g->metrics.horiBearingY)/64; if (ysize < bext) ysize=bext; needr=false; } #endif } if (needr) { if (c=='\t') { if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw*5,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); xpos+=charw*5; if (ysize < ypos+lineh) ysize=ypos+lineh; } else { if (bgmode==OPAQUE) LICE_FillRect(surface,xpos,ypos,charw,lineh,bgcol,1.0f,LICE_BLIT_MODE_COPY); LICE_DrawChar(surface,xpos,ypos,c,fgcol,1.0f,LICE_BLIT_MODE_COPY); if (doUl) LICE_Line(surface,xpos,ypos+lineh+1,xpos+charw,ypos+lineh+1,fgcol,1.0f,LICE_BLIT_MODE_COPY,false); if (ysize < ypos+lineh+(doUl ? 2:1)) ysize=ypos+lineh+(doUl ? 2:1); xpos+=charw; } } } if(xpos>max_xpos)max_xpos=xpos; } if (surface==&clipbm) swell_DirtyContext(ct,clip_x1+left_xpos,clip_y1+start_ypos,clip_x1+max_xpos,clip_y1+start_ypos+ysize); else swell_DirtyContext(ct,left_xpos,start_ypos,max_xpos,start_ypos+ysize); return ysize; }
void EEL_Editor::draw_string(int *ml, int *skipcnt, const char *str, int amt, int *attr, int newAttr, int comment_string_state) { if (amt > 0 && comment_string_state=='"') { while (amt > 0 && *str) { const char *str_scan = str; int varpos,varlen,l=0; while (!l && *str_scan) { while (*str_scan && *str_scan != '%' && str_scan < str+amt) str_scan++; if (str_scan >= str+amt) break; l = parse_format_specifier(str_scan,&varpos,&varlen); if (!l && *str_scan) if (*++str_scan == '%') str_scan++; } if (!*str_scan || str_scan >= str+amt) break; // allow default processing to happen if we reached the end of the string if (l > amt) l=amt; if (str_scan > str) { const int sz=wdl_min(str_scan-str,amt); draw_string_urlchk(ml,skipcnt,str,sz,attr,newAttr); str += sz; amt -= sz; } { const int sz=(varlen>0) ? wdl_min(varpos,amt) : wdl_min(l,amt); if (sz>0) { draw_string_internal(ml,skipcnt,str,sz,attr,SYNTAX_HIGHLIGHT2); str += sz; amt -= sz; } } if (varlen>0) { int sz = wdl_min(varlen,amt); if (sz>0) { draw_string_internal(ml,skipcnt,str,sz,attr,*str == '#' ? SYNTAX_STRINGVAR : SYNTAX_HIGHLIGHT1); amt -= sz; str += sz; } sz = wdl_min(l - varpos - varlen, amt); if (sz>0) { draw_string_internal(ml,skipcnt,str,sz,attr,SYNTAX_HIGHLIGHT2); amt-=sz; str+=sz; } } } } draw_string_urlchk(ml,skipcnt,str,amt,attr,newAttr); }