void cSubtitleObject::DecodeCharacterString(const uchar *Data, int NumberOfCodes) { if (NumberOfCodes > 0) { bool singleByte; const uchar *from = &Data[1]; int len = NumberOfCodes * 2 - 1; cCharSetConv conv(SI::getCharacterTable(from, len, &singleByte)); if (singleByte) { char txt[NumberOfCodes + 1]; char *p = txt; for (int i = 2; i < NumberOfCodes; ++i) { char c = Data[i * 2 + 1] & 0xFF; if (c == 0) break; if (' ' <= c && c <= '~' || c == '\n' || 0xA0 <= c) *(p++) = c; else if (c == 0x8A) *(p++) = '\n'; } *p = 0; const char *s = conv.Convert(txt); Utf8Strn0Cpy(textData, s, Utf8StrLen(s)); } else { // TODO: add proper multibyte support for "UTF-16", "EUC-KR", "GB2312", "GBK", "UTF-8" } } }
void cSkinCursesDisplayMenu::Flush(void) { if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) DrawTitle(); cString date = DayDateTime(); osd->DrawText(ScOsdWidth - Utf8StrLen(date) - 2, 0, date, clrBlack, clrCyan, &Font); osd->Flush(); }
void cSkinCursesDisplayChannel::Flush(void) { if (!message) { cString date = DayDateTime(); osd->DrawText(ScOsdWidth - Utf8StrLen(date), 0, date, clrWhite, clrBackground, &Font); } osd->Flush(); }
int cChannels::MaxShortChannelNameLength(void) { if (!maxShortChannelNameLength) { for (cChannel *channel = First(); channel; channel = Next(channel)) { if (!channel->GroupSep()) maxShortChannelNameLength = max(Utf8StrLen(channel->ShortName(true)), maxShortChannelNameLength); } } return maxShortChannelNameLength; }
void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event) { if (!Event) return; int y = 2; cTextScroller ts; char t[32]; snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString()); ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground); if (Event->Vps() && Event->Vps() != Event->StartTime()) { cString buffer = cString::sprintf(" VPS: %s", *Event->GetVpsString()); osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font); } y += ts.Height(); if (Event->ParentalRating()) { cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString()); osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font); } y += 1; ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Event->Title(), &Font, clrCyan, clrBackground); y += ts.Height(); if (!isempty(Event->ShortText())) { ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Event->ShortText(), &Font, clrYellow, clrBackground); y += ts.Height(); } for (int i = 0; Event->Contents(i); i++) { const char *s = Event->ContentToString(Event->Contents(i)); if (!isempty(s)) { ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, s, &Font, clrYellow, clrBackground); y += 1; } } y += 1; if (!isempty(Event->Description())) { textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Event->Description(), &Font, clrCyan, clrBackground); SetTextScrollbar(); } }
void cSkinCursesDisplayVolume::SetVolume(int Current, int Total, bool Mute) { if (Mute) { osd->DrawRectangle(0, 0, ScOsdWidth - 1, 0, clrTransparent); osd->DrawText(0, 0, tr("Key$Mute"), clrGreen, clrBackground, &Font); } else { const char *Prompt = tr("Volume "); int l = Utf8StrLen(Prompt); int p = (ScOsdWidth - l) * Current / Total; osd->DrawText(0, 0, Prompt, clrGreen, clrBackground, &Font); osd->DrawRectangle(l, 0, l + p - 1, 0, clrGreen); osd->DrawRectangle(l + p, 0, ScOsdWidth - 1, 0, clrWhite); } }
void cSubtitleRegion::UpdateTextData(cSubtitleClut *Clut) { const cPalette *palette = Clut ? Clut->GetPalette(Depth()) : NULL; for (cSubtitleObject *so = objects.First(); so && palette; so = objects.Next(so)) { if (Utf8StrLen(so->TextData()) > 0) { cFont *font = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize); cBitmap tmp(font->Width(so->TextData()), font->Height(), Depth()); double factor = (double)lineHeight / font->Height(); tmp.DrawText(0, 0, so->TextData(), palette->Color(so->ForegroundPixelCode()), palette->Color(so->BackgroundPixelCode()), font); cBitmap *scaled = tmp.Scaled(factor, factor, true); DrawBitmap(so->X(), so->Y(), *scaled); delete scaled; delete font; } } }
void cSkinCursesDisplayMenu::SetRecording(const cRecording *Recording) { if (!Recording) return; const cRecordingInfo *Info = Recording->Info(); int y = 2; cTextScroller ts; char t[32]; snprintf(t, sizeof(t), "%s %s", *DateString(Recording->Start()), *TimeString(Recording->Start())); ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground); y += ts.Height(); if (Info->GetEvent()->ParentalRating()) { cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString()); osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font); } y += 1; const char *Title = Info->Title(); if (isempty(Title)) Title = Recording->Name(); ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Title, &Font, clrCyan, clrBackground); y += ts.Height(); if (!isempty(Info->ShortText())) { ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Info->ShortText(), &Font, clrYellow, clrBackground); y += ts.Height(); } for (int i = 0; Info->GetEvent()->Contents(i); i++) { const char *s = Info->GetEvent()->ContentToString(Info->GetEvent()->Contents(i)); if (!isempty(s)) { ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, s, &Font, clrYellow, clrBackground); y += 1; } } y += 1; if (!isempty(Info->Description())) { textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Info->Description(), &Font, clrCyan, clrBackground); SetTextScrollbar(); } }
// create a new string on the heap that has a maximum 'maxlen' number of // characters (each can span multiple bytes) // // tries to find end of words to break the string // returned char* (if not NULL) must be freed by caller // // bytesCopied used by the caller to jump in the input string char* BreakString(const char*str, int maxlen, int &bytesCopied) { bytesCopied = 0; if (!str) return NULL; // number of chars int symCount = Utf8StrLen(str); // convert UTF-8 multi-byte char to a single uint number uint *inp_sym = new uint[symCount+1]; // +1 for the '\0' int inp_sym_len = Utf8ToArray(str, inp_sym, symCount+1); // number of chars in the string less than the maxlen // TODO: if there is a '\n' in this part! if (inp_sym_len <= maxlen) { // copy the input string bytesCopied = strlen(str); delete[] inp_sym; //printf("** just copied **\n"); return strdup(str); } // create string on heap that can hold maxlen (multi-byte)chars char *s = (char*) malloc((4*maxlen+1)*sizeof(char)); //+1 for '\0' int i = 0; // if no wordbreaks found, break after maxlen characters int line_end = maxlen; // donot show the char that was used to break the string // for eg. ' ' is unnecessary at the end/beginning of a line int skip_symbol = 0; //the string here is longer than requested. Break it down. for (i = 0; i < maxlen; ++i) { //look for word breaks and new lines if (inp_sym[i] == '\0' || inp_sym[i] == '\n') { line_end = i; if (inp_sym[i] != '\0') skip_symbol = 1; break; // found end of line exit loop } else if (inp_sym[i] == ' ') //space { line_end = i; skip_symbol = 1; } }//for // create char from uint array, since the char* is large enough // it will be '\0' terminated bytesCopied = Utf8FromArray(inp_sym, s, 4*maxlen-1,line_end); if (skip_symbol)// jump over the last symbol since it is a ' ' or '\n' ++bytesCopied; delete[] inp_sym; return s; }
void cSkinCursesDisplayReplay::SetTotal(const char *Total) { osd->DrawText(ScOsdWidth - Utf8StrLen(Total), 2, Total, clrWhite, clrBackground, &Font); }
void cSkinCursesDisplayReplay::SetCurrent(const char *Current) { osd->DrawText(0, 2, Current, clrWhite, clrBackground, &Font, Utf8StrLen(Current) + 3); }
virtual int Width(const char *s) const { return s ? Utf8StrLen(s) : 0; }
void cSkinCursesDisplayMenu::Flush(void) { cString date = DayDateTime(); osd->DrawText(ScOsdWidth - Utf8StrLen(date) - 2, 0, date, clrBlack, clrCyan, &Font); osd->Flush(); }