📄 textline.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: textline.cpp,v 1.1.2.1 2004/07/09 01:50:20 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** *////////////////////////////////////////////////////////////////////////////////// textline.cpp//// class TextLine methods.//#include <stdio.h>#include <stdlib.h>#include <string.h>#include "hxtypes.h"#include "hxslist.h" //for base class CHXSimpleList.#include "hxstack.h" //for base class CHXStack.#include "rt_types.h"#include "fontdefs.h"#include "fontinfo.h"#include "txtattrb.h"#include "txtcntnr.h"#include "textline.h"#include "hxstrutl.h"#include "parsing.h"#include "netbyte.h"#ifdef _WINDOWS#ifdef _WIN16#include <windows.h>#endif /* _WIN16 */#endif /* _WINDOWS */#include "txtwindw.h"#include "hxheap.h"#ifdef _DEBUG#undef HX_THIS_FILE static char HX_THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////////// Constructor://// Note: if ulEndByteInFile is 0, this means it's not yet known and must be// set later.//TextLine::TextLine(TextLine& refTL) : TextAttributes(refTL), m_ulLineNumOfFile(0L) , m_ulStartByteInFile(0L) , m_ulEndByteInFile(0L) , m_ulTimeOfLastClear(TIME_INVALID) , m_ulStartByteOfMatchingFontTagInFile(0L) , m_bSomethingChanged(TRUE){ //let the default copy constructor do its thing (memcopy the members of // refTL into *this). There are no members that are pointers, so this // will work just fine.}//This constructor allows us to create a font-attribute only T.L. for// keeping track of what the state of the font stacks is right after// a </FONT..> tag is seen:TextLine::TextLine( ULONG32 ulStartByteOfFontUndoTagInFile, ULONG32 ulEndByteOfFontUndoTagInFile, ULONG32 ulStartByteOfMatchingFontTagInFile, ULONG32 ulFontPointSize, COLORTYPE ulTextColor, COLORTYPE ulTextBGColor, ULONG32 ulFontCharset, ULONG32 ulFontFace, ULONG32 ulMinorContentVersion, ULONG32 ulMajorContentVersion){ m_ulStartByteInFile = ulStartByteOfFontUndoTagInFile; m_ulEndByteInFile = ulEndByteOfFontUndoTagInFile; m_ulStartByteOfMatchingFontTagInFile =ulStartByteOfMatchingFontTagInFile; setFontPointSize(ulFontPointSize); setTextColor(ulTextColor); setTextBackgroundColor(ulTextBGColor); setFontCharset(ulFontCharset); setFontFace(ulFontFace);}///////////////////////////////////////////////////////////////////////////////// Decides what's different from the default vals and adds it to what// will be sent at the start of a packet so that everything in the// packet gets rendered properly, even if prior packet was lost.// Fills pPacketHeaderBuf, with these & other values, in marked-up text form.//// Note: if a val is the same as the default val for the stream, the// fact that the val was not sent tells the renderer to use the default.//ULONG32 TextLine::OutputPacketHeaderString( ULONG32 ulDataID, TextWindow* pTextWin, BOOL bStateIsGetPacketSeekBackReadPending, char* pPacketHeaderBuf, ULONG32 packetHeaderBufSize, TextLineList* pFontUndoTagList, ULONG32 ulPacketLen){//Pkt hdr starts with <nnnn> where nnnn is a 4-digit, base 10 number telling// the size of the entire header in bytes (so the renderer doesn't have to// parse it to find the end):#define NUM_DIGITS_IN_START_TAG_OF_PKT_HDR 4//Add 2 for the '<' and '>':#define LEN_OF_START_TAG_OF_PKT_HDR NUM_DIGITS_IN_START_TAG_OF_PKT_HDR+2//Add 1 more for the '/' (</nnnn> ends the header, but is not really needed):#define LEN_OF_END_TAG_OF_PKT_HDR LEN_OF_START_TAG_OF_PKT_HDR+1#define MIN_TEMPBUF_LEN 128 if(!pTextWin) { return 0; } ULONG32 ulTextWindowType = pTextWin->getType(); BOOL bIsLiveSource = pTextWin->isLiveSource(); if(packetHeaderBufSize < LEN_OF_START_TAG_OF_PKT_HDR+LEN_OF_END_TAG_OF_PKT_HDR) { return 0L; } ULONG32 ulStartByteOfThisPacket = getStartByteInFile(); ULONG32 ulEndByteOfThisPacket = ulStartByteOfThisPacket + ulPacketLen-1; ULONG32 HREFbufLen = getHrefBufLen(); if(HREFbufLen && !getHrefBuf()) { HREFbufLen = 0L; } //This is needed for hrefs that have target="_player" (and possibly // other parameters to the <A> (anchor) tag in addition to the URL // specified in href="URL" string: ULONG32 ulExtraLen = 128; char* pTmp = new char[HREFbufLen+1>MIN_TEMPBUF_LEN? ulExtraLen+HREFbufLen+1:ulExtraLen+MIN_TEMPBUF_LEN]; if(!pTmp) { return 0L; //Mem alloc failed. } pTmp[0] = '\0';#define TMP_FONT_INFO_BUF_SIZE 32 char pTmpFontInfoBuf[TMP_FONT_INFO_BUF_SIZE]; /* Flawfinder: ignore */ pTmpFontInfoBuf[0] = '\0'; const char pFontIntroStr[] = "<FONT "; const char pTimeIntroStr[] = "<TIME "; BOOL bFontTagWasStarted = FALSE; BOOL bTimeTagWasStarted = FALSE; pPacketHeaderBuf[0] = '\0';/// if(!bStateIsGetPacketSeekBackReadPending) //XXXEH-do this for ALL states? { //fill with NUM_DIGITS_IN_START_TAG_OF_PKT_HDR zeros for now: SafeStrCat(pPacketHeaderBuf, "<0000>", packetHeaderBufSize); } ULONG32 pktHdrLen = strlen(pPacketHeaderBuf) + LEN_OF_END_TAG_OF_PKT_HDR; ULONG32 ulSprintfLen = 0L; //These are an internal set of values used by the renderer. // (1) the <RESET> tag tells the renderer to kill all prior text whose // time|position is no longer valid. // (2) the <DATA ID= > is used by the renderer to know what data this // is (NOT what packet it is) because the live encoder may resend data // in a new packet and this ID identifies it so that the renderer can // ignore the packet if it has already seen the data with that ID. // (3) <POS X0= Y0= > is used by the renderer to figure out where to draw // the first data in this packet; X0 and Y0 are where to draw it at // time zero (or at time of last clear if <TIME LC=> is sent); the // renderer then uses the scrollrate and crawlrate to figure out where // to draw this text at its starttime; if(/* //XXXEH- RESET *all* data, not just back-seeking (...right???): bStateIsGetPacketSeekBackReadPending || */ !pTextWin->isLooping()) { SafeStrCat(pPacketHeaderBuf, "<RESET>", packetHeaderBufSize); pktHdrLen = strlen(pPacketHeaderBuf) + LEN_OF_END_TAG_OF_PKT_HDR; } //For now, data ID must be non-zero if live, else zero: HX_ASSERT((ulDataID && bIsLiveSource) || (!ulDataID && !bIsLiveSource)); if(ulDataID) //(else is invalid ID so don't insert a DATA tag) { ulSprintfLen = sprintf(pTmp, "<DATA ID=%ld>", /* Flawfinder: ignore */ ulDataID); if(pktHdrLen+ulSprintfLen < packetHeaderBufSize) { SafeStrCat(pPacketHeaderBuf, pTmp, packetHeaderBufSize); pktHdrLen += ulSprintfLen; } } //Do this before doing the "<POS ..>" below or else both will force // 2 line breaks for a total of 4, since POS already accounts for the // line breaks that the POS tag caused: if(isPreFormatted()) { if(pktHdrLen+8 < packetHeaderBufSize) { SafeStrCat(pPacketHeaderBuf, "<PRE>", packetHeaderBufSize); pktHdrLen+=5; } } { ULONG32 ulNewLinesAtStart = getNumNewlinesAtStart(); ulSprintfLen = sprintf(pTmp, "<POS X0=%ld Y0=%ld NEWLINES=%ld>", /* Flawfinder: ignore */ getXAtTimeZeroUpperLeftCorner(), getYAtTimeZeroUpperLeftCorner(), ulNewLinesAtStart); //"NEWLINES=", above, tells renderer whether or not the text of this // TextLine, which is starting a packet, immediately followed a line // break (so the renderer can properly handle CENTERing this text, // which is not considered in the file format when it computes the // X-POS of the text); a TextLine does not necessarily start a new // line since it may be merely a piece of a line that was too large. if(pktHdrLen+ulSprintfLen < packetHeaderBufSize) { SafeStrCat(pPacketHeaderBuf, pTmp, packetHeaderBufSize); pktHdrLen += ulSprintfLen; } } COLORTYPE defaultTextColor = DEFAULT_TEXT_COLOR; COLORTYPE defaultTextBGColor = DEFAULT_TEXT_BGCOLOR; ULONG32 defaultFontPointSize = DEFAULT_FONT_PTSIZE; ULONG32 defaultFontCharset = CHARSET__default; ULONG32 defaultFontFaceIndex = DEFAULT_FONT_FACE_INDX; //Go through the pFontUndoTagList and see if any of them are between the // ulStartByteOfThisPacket and ulEndByteOfThisPacket of this packet and, // if so, prepend their values to the packet header: //XXXEH- a more efficient thing to do would be to only do this for any // </FONT> tags in this packet that do not have their matching <FONT> // tags preceding them in this packet, but we'll need to keep track of // where each <FONT> tag is first... //Search from the end of the pFontUndoTagList and look for the first // node whose startByteInFile is between ulStartByteOfThisPacket and // ulEndByteOfThisPacket: ULONG32 listSize; ULONG32 ulNumFontUndoTagsInThisPacket = 0L; if(pFontUndoTagList && (listSize = pFontUndoTagList->size())>0L) { LISTPOSITION pos = pFontUndoTagList->GetEndPosition(); while(pos) { TextLine* pTL = (TextLine*)pFontUndoTagList->GetAt(pos); HX_ASSERT_VALID_PTR(pTL); if(pTL) { //Added bIsLiveSource check because live version might not // keep track properly (since it's not necessarily reading // from a file) and the matching <FONT> may truly be AFTER // the </FONT> since each packet is considered to start at // position 0 of the virtual file: HX_ASSERT(bIsLiveSource? TRUE : pTL->getStartByteOfMatchingFontTagInFile() < pTL->getStartByteInFile()); BOOL bMatchingFontTagIsInAPreviousPacket = pTL->getStartByteOfMatchingFontTagInFile() < ulStartByteOfThisPacket; if(bIsLiveSource) { //Note: live version might not keep track of locations in // the "file" properly (since it is not necessarily // reading from a file) and the matching <FONT> may truly // be AFTER the </FONT> since each packet is considered // to start at position 0 of the virtual file, e.g., a // "<FONT>" at location 400 of the prior packet could be // followed by the "</FONT>" at location 300 of the // current packet: if(pTL->getStartByteOfMatchingFontTagInFile() >= pTL->getStartByteInFile()) { bMatchingFontTagIsInAPreviousPacket = TRUE; } } if(pTL->getStartByteInFile() < ulEndByteOfThisPacket && pTL->getEndByteInFile() > ulStartByteOfThisPacket && bMatchingFontTagIsInAPreviousPacket) { ulNumFontUndoTagsInThisPacket++; COLORTYPE textColor = pTL->getTextColor(); COLORTYPE textBGColor = pTL->getTextBackgroundColor(); ULONG32 ptSize = pTL->getFontPointSize(); ULONG32 fontCharset = pTL->getFontCharset(); ULONG32 fontFaceIndex = pTL->getFontFace(); if(textColor != BAD_RGB_COLOR) { if(pTL->getSomethingChanged()) { defaultTextColor = textColor; } textColor = DwToNet(textColor); UCHAR* pc = (UCHAR *)&textColor; if(textBGColor != TRANSPARENT_COLOR) { ulSprintfLen = sprintf(pTmp, /* Flawfinder: ignore */ "%scolor=#%02X%02X%02X", bFontTagWasStarted?" ":pFontIntroStr, pc[1],pc[2],pc[3]); } else { ulSprintfLen = sprintf(pTmp, /* Flawfinder: ignore */ "%scolor=transparent", bFontTagWasStarted?" ":pFontIntroStr); } if(pktHdrLen+ulSprintfLen < packetHeaderBufSize-1) { SafeStrCat(pPacketHeaderBuf, pTmp, packetHeaderBufSize); pktHdrLen += ulSprintfLen; bFontTagWasStarted = TRUE; } } if(textBGColor != BAD_RGB_COLOR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -