Example #1
0
IRIRef *IRIRef::urify() throw(BadAllocException) {
  if (this->urified) {
    return this;
  }
  const uint8_t *begin = this->utf8str->dptr();
  const uint8_t *end = begin + this->utf8str->size();
  const uint8_t *mark = begin;
  const uint8_t *next = NULL;
  uint32_t codepoint;
  while (mark != end) {
    codepoint = utf8char(mark, &next);
    if (IRIRef::isIPrivate(codepoint) || IRIRef::isUCSChar(codepoint)) {
      break;
    }
    mark = next;
  }
  if (mark == end) {
    this->urified = true;
    return this;
  }
  vector<uint8_t> urivec;
  urivec.reserve(this->utf8str->size() + 2);
  do {
    urivec.insert(urivec.end(), begin, mark);
    for (; mark != next; ++mark) {
      urivec.push_back(to_ascii('%'));
      uint8_t hi4 = (*mark) >> 4;
      uint8_t lo4 = (*mark) & UINT8_C(0x0F);
      urivec.push_back(hi4 <= UINT8_C(9) ? to_ascii('0') + hi4
                                         : to_ascii('A') + (hi4 - 10));
      urivec.push_back(lo4 <= UINT8_C(9) ? to_ascii('0') + lo4
                                         : to_ascii('A') + (lo4 - 10));
    }
    begin = mark;
    while (mark != end) {
      codepoint = utf8char(mark, &next);
      if (IRIRef::isIPrivate(codepoint) || IRIRef::isUCSChar(codepoint)) {
        break;
      }
      mark = next;
    }
  } while(mark != end);
  urivec.insert(urivec.end(), begin, mark);
  MPtr<uint8_t> *uristr;
  try {
    NEW(uristr, MPtr<uint8_t>, urivec.size());
  } RETHROW_BAD_ALLOC
  copy(urivec.begin(), urivec.end(), uristr->dptr());
  this->utf8str->drop();
  this->utf8str = uristr;
  this->urified = true;
  return this; 
}
Example #2
0
void Utf8Charset::push_back(int amount, unicode_t unicode, ...)
{
	unicode_t val;
	UnicodeGroup unicodegroup;

	if(amount <= 0) return;

	unicodegroup.array.push_back(unicode);

	va_list vl;
	va_start(vl, unicode);
	for (int i = 1; i < amount; i++)
  	{
    		val = va_arg(vl, unicode_t);
		unicodegroup.array.push_back(val);
  	}
  	va_end(vl);

	unicodegroup.group_code = unicode;
	
	Utf8Char utf8char(unicode);
	unicodegroup.output_string = utf8char.tostring();
	unicodegroup.flags = 0x0;
	unicodegroup.index = this->charset.size();

	this->charset.push_back(unicodegroup);

}
Example #3
0
void Utf8Charset::push_back(unicode_t group_code, std::string output_string, unsigned int flags, int amount, unicode_t unicode, ...)
{
	unicode_t val;
	UnicodeGroup unicodegroup;

	if(amount <= 0) return;

	unicodegroup.array.push_back(unicode);

	va_list vl;
	va_start(vl, unicode);
	for (int i = 1; i < amount; i++)
  	{
    		val = va_arg(vl, unicode_t);
		unicodegroup.array.push_back(val);
  	}
  	va_end(vl);

	if (group_code != 0)
		unicodegroup.group_code = group_code;
	else
		unicodegroup.group_code = unicode;
	
	if (!output_string.empty())
		unicodegroup.output_string = output_string;
	else
	{
		Utf8Char utf8char(unicode);
		unicodegroup.output_string = utf8char.tostring();
	}
	
	unicodegroup.flags = flags;

	this->charset.push_back(unicodegroup);

}
Example #4
0
IRIRef *IRIRef::normalize() THROWS(BadAllocException, TraceableException) {
  if (this->normalized && !this->urified) {
    return this;
  }

  uint8_t *normed = NULL;
  DPtr<uint8_t> *normal = NULL;

  if (this->utf8str->standable()) {
    this->utf8str = this->utf8str->stand();
    normal = this->utf8str;
    normal->hold();
  } else {
    NEW(normal, MPtr<uint8_t>, this->utf8str->size());
  }
  normed = normal->dptr();

  // Percent encoding; decode if IUnreserved
  uint8_t bits = UINT8_C(0);
  uint8_t *begin = this->utf8str->dptr();
  uint8_t *end = begin + this->utf8str->size();
  uint8_t *marki = begin;
  uint8_t *markj = begin;
  uint8_t *markk = normed;
  for (; marki != end; marki = markj) {
    for (markj = marki; markj != end && *markj != to_ascii('%'); ++markj) {
      // loop does the work
    }
    size_t sz = markj - marki;
    memmove(markk, marki, sz * sizeof(uint8_t));
    markk += sz;
    if (markj == end) {
      break;
    }

    uint8_t enc[4] = { UINT8_C(0xFF), UINT8_C(0xFF),
                       UINT8_C(0xFF), UINT8_C(0xFF) };
    enc[0] = (((uint8_t) IRI_HEX_VALUE(markj[1])) << 4)
             | (uint8_t) IRI_HEX_VALUE(markj[2]);
    if (enc[0] <= UINT8_C(0x7F)) {
      if (IRIRef::isIUnreserved(enc[0])) {
        *markk = enc[0];
        ++markk;
      } else {
        markk[0] = markj[0];
        markk[1] = to_upper(markj[1]);
        markk[2] = to_upper(markj[2]);
        markk += 3;
      }
      markj += 3;
      continue;
    }

    uint8_t *markl = markj + 3;
    int i = 1;
    uint8_t bits;
    for (bits = enc[0] << 1; markl != end && *markl == to_ascii('%') &&
                             bits > UINT8_C(0x7F) && i < 4; bits <<= 1) {
      enc[i] = (((uint8_t) IRI_HEX_VALUE(markl[1])) << 4)
               | (uint8_t) IRI_HEX_VALUE(markl[2]);
      markl += 3;
      ++i;
    }
    try {
      const uint8_t *endenc;
      uint32_t codepoint = utf8char(enc, &endenc);
      if (IRIRef::isIUnreserved(codepoint)) {
        i = endenc - enc; // should already be equal, but just in case
        memmove(markk, enc, i * sizeof(uint8_t));
        markk += i;
        markj = markl;
        this->urified = false;
      } else {
        for (; markj != markl; markj += 3) {
          markk[0] = markj[0];
          markk[1] = to_upper(markj[1]);
          markk[2] = to_upper(markj[2]);
          markk += 3;
        }
      }
    } catch (InvalidEncodingException &e) {
      markk[0] = markj[0];
      markk[1] = to_upper(markj[1]);
      markk[2] = to_upper(markj[2]);
      markk += 3;
      markj += 3;
    }
  }
  if (markk != end) {
    DPtr<uint8_t> *temp = normal->sub(0, markk - normed);
    normal->drop();
    normal = temp;
  }

  if (this->normalized) {
    this->utf8str->drop();
    this->utf8str = normal;
    return this;
  }

  // Character normalization; NFC
  DPtr<uint32_t> *codepoints = utf8dec(normal);
  normal->drop();
  DPtr<uint32_t> *codepoints2 = nfc_opt(codepoints);
  codepoints->drop();
  normal = utf8enc(codepoints2);
  codepoints2->drop();
  this->utf8str->drop();
  this->utf8str = normal;

  // Path normalization
  this->resolve(NULL);

  // Case normalization; scheme and host
  DPtr<uint8_t> *part = this->getPart(SCHEME);
  if (part != NULL) {
    begin = part->dptr();
    end = begin + part->size();
    for (; begin != end; ++begin) {
      *begin = to_lower(*begin);
    }
    part->drop();
  }
  part = this->getPart(HOST);
  if (part != NULL) {
    begin = part->dptr();
    end = begin + part->size();
    for (; begin != end; ++begin) {
      *begin = to_lower(*begin);
    }
    part->drop();
  }

  this->normalized = true;
  return this;
}
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;
}