static int MatchOne( DaoRegex *self, DaoRgxItem *patt, daoint pos ) { DCharState st = { 0, 1, 0 }; DCharState st2 = { 0, 1, 0 }; uint_t ch, ch2, b1, b2; int i; patt->offset = 0; patt->count += 1; switch( patt->type ){ case PAT_WBORDER : if( pos == self->start || pos >= self->end ) return 1; for(i=1; i <= 4 && (pos-i) >= self->start; ++i){ st = DString_DecodeChar( self->source + pos - i, self->source + self->end ); if( i == 1 ) st2 = st; if( st.type == i ) break; } if( st.type == 0 ) st = st2; st2 = DString_DecodeChar( self->source + pos, self->source + self->end ); if( dao_character( st.value ) != dao_character( st2.value ) ) return 1; return 0; case PAT_ANY : if( pos >= self->end ) return 0; st = DString_DecodeChar( self->source + pos, self->source + self->end ); if( pos + st.width > self->end ) st.width = 1; patt->offset = st.width; return 1; case PAT_SPLIT: case PAT_BEGIN: case PAT_JOIN: return 1; case PAT_START: return (pos == self->start); case PAT_END : return (pos >= self->end); case PAT_SET : return MatchSet( self, patt, pos ); case PAT_WORD : return MatchWord( self, patt, pos ); case PAT_PAIR : return MatchPair( self, patt, pos ); case PAT_PATPAIR : return MatchPatPair( self, patt, pos ); case PAT_BACKREF: return MatchBackRef( self, patt, pos ); default : break; } if( pos >= self->end ) return 0; st = DString_DecodeChar( self->source + pos, self->source + self->end ); if( st.type == 0 ) return 0; patt->offset = st.width; ch = ch2 = st.value; if( sizeof(wchar_t) == 2 && ch > 0xFFFF ) ch = 0; /* for isw*(); */ switch( patt->type ){ case 'a' : return iswalpha( ch ); case 's' : return iswspace( ch ); case 'k' : return iswcntrl( ch ); case 'p' : return iswpunct( ch ); case 'd' : return iswdigit( ch ); case 'x' : return iswxdigit( ch ); case 'e' : return dao_cjk( ch2 ); case 'w' : return dao_character( ch2 ); case 'c' : return iswlower( ch ); case 'A' : return ! iswalpha( ch ); case 'S' : return ! iswspace( ch ); case 'K' : return ! iswcntrl( ch ); case 'P' : return ! iswpunct( ch ); case 'D' : return ! iswdigit( ch ); case 'X' : return ! iswxdigit( ch ); case 'E' : return ! dao_cjk( ch2 ); case 'W' : return ! dao_character( ch2 ); case 'C' : return iswupper( ch ); default : return 0; } return 0; }
static int Ispunct(int c) { return iswpunct(c); }
int iswpunct_l(wint_t c, locale_t) { return iswpunct(c); }
bool isPunct(UChar c) { return !!iswpunct(c); }
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const { if (!wchars || !wchars[0] || max_chars == 0) { return 0; } llassert(max_pixels >= 0.f); llassert(max_chars >= 0); BOOL clip = FALSE; F32 cur_x = 0; S32 start_of_last_word = 0; BOOL in_word = FALSE; // avoid S32 overflow when max_pixels == S32_MAX by staying in floating point F32 scaled_max_pixels = max_pixels * sScaleX; F32 width_padding = 0.f; LLFontGlyphInfo* next_glyph = NULL; S32 i; for (i=0; (i < max_chars); i++) { llwchar wch = wchars[i]; if(wch == 0) { // Null terminator. We're done. break; } if (in_word) { if (iswspace(wch)) { if(wch !=(0x00A0)) { in_word = FALSE; } } if (iswindividual(wch)) { if (iswpunct(wchars[i+1])) { in_word=TRUE; } else { in_word=FALSE; start_of_last_word = i; } } } else { start_of_last_word = i; if (!iswspace(wch)||!iswindividual(wch)) { in_word = TRUE; } } LLFontGlyphInfo* fgi = next_glyph; next_glyph = NULL; if(!fgi) { fgi = mFontFreetype->getGlyphInfo(wch); if (NULL == fgi) { return 0; } } // account for glyphs that run beyond the starting point for the next glyphs width_padding = llmax( 0.f, // always use positive padding amount width_padding - fgi->mXAdvance, // previous padding left over after advance of current character (F32)(fgi->mWidth + fgi->mXBearing) - fgi->mXAdvance); // difference between width of this character and advance to next character cur_x += fgi->mXAdvance; // clip if current character runs past scaled_max_pixels (using width_padding) if (scaled_max_pixels < cur_x + width_padding) { clip = TRUE; break; } if (((i+1) < max_chars) && wchars[i+1]) { // Kern this puppy. next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]); cur_x += mFontFreetype->getXKerning(fgi, next_glyph); } // Round after kerning. cur_x = ll_round(cur_x); } if( clip ) { switch (end_on_word_boundary) { case ONLY_WORD_BOUNDARIES: i = start_of_last_word; break; case WORD_BOUNDARY_IF_POSSIBLE: if (start_of_last_word != 0) { i = start_of_last_word; } break; default: case ANYWHERE: // do nothing break; } } return i; }
int word_separator::default_word_type(utf32_point c) { if (iswspace(c)) return 0; else if (iswalnum(c)) return 1; else if (iswpunct(c)) return 2; else return 3; }
extern "C" const WCHAR *FormatRaw(DWORD dwFlags, const WCHAR *msg, int flags, const char *szProto, HANDLE hContact, BOOL *clr_added) { bool clr_was_added = false, was_added; static std::wstring message(msg); unsigned beginmark = 0, endmark = 0, tempmark = 0, index; int i, endindex; WCHAR endmarker; message.assign(msg); #ifdef __MATHMOD_SUPPORT if(myGlobals.m_MathModAvail && message.find(myGlobals.m_MathModStartDelimiter) != message.npos) return(message.c_str()); #endif if(HIWORD(flags) == 0) goto nobbcode; if(iHaveSmileyadd == -1) iHaveSmileyadd = MY_ServiceExists(MS_SMILEYADD_BATCHPARSE); beginmark = 0; while(TRUE) { for(i = 0; i < NR_CODES; i++) { if((tempmark = message.find(w_bbcodes_begin[i], 0)) != message.npos) break; } if(i >= NR_CODES) break; beginmark = tempmark; endindex = i; endmark = message.find(w_bbcodes_end[i], beginmark); if(endindex == 4) { // color size_t closing = message.find_first_of(L"]", beginmark); was_added = false; if(closing == message.npos) { // must be an invalid [color=] tag w/o closing bracket message[beginmark] = ' '; continue; } else { std::wstring colorname = message.substr(beginmark + 7, 8); search_again: bool clr_found = false; unsigned int ii = 0; wchar_t szTemp[5]; for(ii = 0; ii < g_ctable_size; ii++) { if(!_wcsnicmp((wchar_t *)colorname.c_str(), rtf_ctable[ii].szName, lstrlen(rtf_ctable[ii].szName))) { closing = beginmark + 7 + wcslen(rtf_ctable[ii].szName); if(endmark != message.npos) { message.erase(endmark, 4); message.replace(endmark, 4, L"c0 "); } message.erase(beginmark, (closing - beginmark)); message.insert(beginmark, L"cxxx "); _snwprintf(szTemp, 4, L"%02d", MSGDLGFONTCOUNT + 10 + ii); message[beginmark + 3] = szTemp[0]; message[beginmark + 4] = szTemp[1]; clr_found = true; if(was_added) { wchar_t wszTemp[100]; _snwprintf(wszTemp, 100, L"##col##%06u:%04u", endmark - closing, ii); wszTemp[99] = 0; message.insert(beginmark, wszTemp); } break; } } if(!clr_found) { size_t c_closing = colorname.find_first_of(L"]", 0); if(c_closing == colorname.npos) c_closing = colorname.length(); const wchar_t *wszColname = colorname.c_str(); if(endmark != message.npos && c_closing > 2 && c_closing <= 6 && iswalnum(colorname[0]) && iswalnum(colorname[c_closing -1])) { RTF_ColorAdd(wszColname, c_closing); if(!was_added) { clr_was_added = was_added = true; goto search_again; } else goto invalid_code; } else { invalid_code: if(endmark != message.npos) message.erase(endmark, 8); if(closing != message.npos && closing < endmark) message.erase(beginmark, (closing - beginmark) + 1); else message[beginmark] = ' '; } } continue; } } if(endmark != message.npos) message.replace(endmark, 4, formatting_strings_end[i]); message.insert(beginmark, L" "); message.replace(beginmark, 4, formatting_strings_begin[i]); } nobbcode: if(message.find(L"://") != message.npos) goto nosimpletags; if(!(dwFlags & MWF_LOG_TEXTFORMAT)) goto nosimpletags; while((beginmark = message.find_first_of(L"*/_", beginmark)) != message.npos) { endmarker = message[beginmark]; if(LOWORD(flags)) { if(beginmark > 0 && !iswspace(message[beginmark - 1]) && !iswpunct(message[beginmark - 1])) { beginmark++; continue; } // search a corresponding endmarker which fulfills the criteria unsigned tempmark = beginmark + 1; while((endmark = message.find(endmarker, tempmark)) != message.npos) { if(iswpunct(message[endmark + 1]) || iswspace(message[endmark + 1]) || message[endmark + 1] == 0 || wcschr(L"*/_", message[endmark + 1]) != NULL) goto ok; tempmark = endmark + 1; } break; } else { if((endmark = message.find(endmarker, beginmark + 1)) == message.npos) break; } ok: if((endmark - beginmark) < 2) { beginmark++; continue; } index = 0; switch(endmarker) { case '*': index = 0; break; case '/': index = 1; break; case '_': index = 2; break; } /* * check if the code enclosed by simple formatting tags is a valid smiley code and skip formatting if * it really is one. */ if(iHaveSmileyadd && endmark > beginmark + 1) { std::wstring smcode; smcode.assign(message, beginmark, (endmark - beginmark) + 1); SMADD_BATCHPARSE2 smbp = {0}; SMADD_BATCHPARSERES *smbpr; smbp.cbSize = sizeof(smbp); smbp.Protocolname = szProto; smbp.flag = SAFL_TCHAR | SAFL_PATH; smbp.str = (TCHAR *)smcode.c_str(); smbp.hContact = hContact; smbpr = (SMADD_BATCHPARSERES *)MY_CallService(MS_SMILEYADD_BATCHPARSE, 0, (LPARAM)&smbp); if(smbpr) { MY_CallService(MS_SMILEYADD_BATCHFREE, 0, (LPARAM)smbpr); beginmark = endmark + 1; continue; } } message.insert(endmark, L"%%%"); message.replace(endmark, 4, formatting_strings_end[index]); message.insert(beginmark, L"%%%"); message.replace(beginmark, 4, formatting_strings_begin[index]); } nosimpletags: if(clr_added) *clr_added = clr_was_added; return(message.c_str()); }