// This isn't an MHEG action as such but is used as part of the implementation of "Clone" public override void MakeClone(MHRoot pTarget, MHRoot pRef, MHEngine engine) { MHIngredient pClone = pTarget.Clone(engine); // Clone it. pClone.ObjectIdentifier.GroupId.Copy(m_ObjectIdentifier.GroupId); // Group id is the same as this. pClone.ObjectIdentifier.ObjectNo = ++m_nLastId; // Create a new object id. m_Items.Append(pClone); // Set the object reference result to the newly constructed ref. pRef.SetVariableValue(new MHUnion(pClone.ObjectIdentifier)); pClone.Preparation(engine); // Prepare the clone. }
public void Initialise(MHParseNode p, MHEngine engine) { for (int i = 0; i < p.GetSeqCount(); i++) { m_Movement.Append(p.GetSeqN(i).GetIntValue()); } }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); MHParseNode pMultiplex = p.GetNamedArg(ASN1Codes.C_MULTIPLEX); for (int i = 0; i < pMultiplex.GetArgCount(); i++) { MHParseNode pItem = pMultiplex.GetArgN(i); if (pItem.GetTagNo() == ASN1Codes.C_AUDIO) { MHAudio pAudio = new MHAudio(); m_Multiplex.Append(pAudio); pAudio.Initialise(pItem, engine); } else if (pItem.GetTagNo() == ASN1Codes.C_VIDEO) { MHVideo pVideo = new MHVideo(); m_Multiplex.Append(pVideo); pVideo.Initialise(pItem, engine); } else if (pItem.GetTagNo() == ASN1Codes.C_RTGRAPHICS) { MHRTGraphics pRtGraph = new MHRTGraphics(); m_Multiplex.Append(pRtGraph); pRtGraph.Initialise(pItem, engine); } // Ignore unknown items } MHParseNode pStorage = p.GetNamedArg(ASN1Codes.C_STORAGE); if (pStorage != null) { m_nStorage = pStorage.GetArgN(0).GetEnumValue(); } MHParseNode pLooping = p.GetNamedArg(ASN1Codes.C_LOOPING); if (pLooping != null) { m_nLooping = pLooping.GetArgN(0).GetIntValue(); } }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); MHParseNode args = p.GetArgN(1); for (int i = 0; i < args.GetSeqCount(); i++) { MHPointArg pPoint = new MHPointArg(); m_Points.Append(pPoint); pPoint.Initialise(args.GetSeqN(i), engine); } }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); // Target m_Succeeded.Initialise(p.GetArgN(1), engine); // Call/fork succeeded flag // Arguments. MHParseNode args = p.GetArgN(2); for (int i = 0; i < args.GetSeqCount(); i++) { MHParameter pParm = new MHParameter(); m_Parameters.Append(pParm); pParm.Initialise(args.GetSeqN(i), engine); } }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); // Target m_Succeeded.Initialise(p.GetArgN(1), engine); MHParseNode pVarSeq = p.GetArgN(2); for (int i = 0; i < pVarSeq.GetSeqCount(); i++) { MHObjectRef pVar = new MHObjectRef(); m_Variables.Append(pVar); pVar.Initialise(pVarSeq.GetSeqN(i), engine); } m_FileName.Initialise(p.GetArgN(3), engine); }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); MHParseNode pMovements = p.GetNamedArg(ASN1Codes.C_MOVEMENT_TABLE); if (pMovements != null) { for (int i = 0; i < pMovements.GetArgCount(); i++) { MHMovement pMove = new MHMovement(); m_MovementTable.Append(pMove); pMove.Initialise(pMovements.GetArgN(i), engine); } } MHParseNode pTokenGrp = p.GetNamedArg(ASN1Codes.C_TOKEN_GROUP_ITEMS); if (pTokenGrp != null) { for (int i = 0; i < pTokenGrp.GetArgCount(); i++) { MHTokenGroupItem pToken = new MHTokenGroupItem(); m_TokenGrpItems.Append(pToken); pToken.Initialise(pTokenGrp.GetArgN(i), engine); } } MHParseNode pNoToken = p.GetNamedArg(ASN1Codes.C_NO_TOKEN_ACTION_SLOTS); if (pNoToken != null) { for (int i = 0; i < pNoToken.GetArgCount(); i++) { MHParseNode pAct = pNoToken.GetArgN(i); MHActionSequence pActions = new MHActionSequence(); m_NoTokenActionSlots.Append(pActions); // The action slot entry may be NULL. if (pAct.NodeType != MHParseNode.PNNull) { pActions.Initialise(pAct, engine); } } } }
public void Initialise(MHParseNode p, MHEngine engine) { // A pair consisting of an object reference and an optional action slot sequence. m_Object.Initialise(p.GetSeqN(0), engine); if (p.GetSeqCount() > 1) { MHParseNode pSlots = p.GetSeqN(1); for (int i = 0; i < pSlots.GetSeqCount(); i++) { MHParseNode pAct = pSlots.GetSeqN(i); MHActionSequence pActions = new MHActionSequence(); m_ActionSlots.Append(pActions); // The action slot entry may be NULL. if (pAct.NodeType != MHParseNode.PNNull) { pActions.Initialise(pAct, engine); } } } }
public override void Initialise(MHParseNode p, MHEngine engine) { base.Initialise(p, engine); MHParseNode pPositions = p.GetNamedArg(ASN1Codes.C_POSITIONS); for (int i = 0; i < pPositions.GetArgCount(); i++) { MHParseNode pPos = pPositions.GetArgN(i); Point pos = new Point(pPos.GetSeqN(0).GetIntValue(), pPos.GetSeqN(1).GetIntValue()); m_Positions.Append(pos); } MHParseNode pWrap = p.GetNamedArg(ASN1Codes.C_WRAP_AROUND); if (pWrap != null) { m_fWrapAround = pWrap.GetArgN(0).GetBoolValue(); } MHParseNode pMultiple = p.GetNamedArg(ASN1Codes.C_MULTIPLE_SELECTION); if (pMultiple != null) { m_fMultipleSelection = pMultiple.GetArgN(0).GetBoolValue(); } }
// UK MHEG specifies the use of the Tiresias font and broadcasters appear to // assume that all MHEG applications will lay the text out in the same way. // Recreate the image. protected void Redraw() { if (!RunningStatus || m_pDisplay == null) { return; } if (m_nBoxWidth == 0 || m_nBoxHeight == 0) { return; // Can't draw zero sized boxes. } m_pDisplay.SetSize(m_nBoxWidth, m_nBoxHeight); m_pDisplay.Clear(); MHRgba textColour = GetColour(m_textColour); // Process any escapes in the text and construct the text arrays. MHSequence <MHTextLine> theText = new MHSequence <MHTextLine>(); // Set up the first item on the first line. MHTextItem pCurrItem = new MHTextItem(); MHTextLine pCurrLine = new MHTextLine(); pCurrLine.Items.Append(pCurrItem); theText.Append(pCurrLine); Stack <MHRgba> m_ColourStack = new Stack <MHRgba>(); // Stack to handle nested colour codes. m_ColourStack.Push(textColour); pCurrItem.Colour = textColour; int i = 0; while (i < m_Content.Size) { char ch = m_Content.GetAt(i++); if (ch == '\t') // Tab - start a new item if we have any text in the existing one. { if (pCurrItem.Text.Size != 0) { pCurrItem = pCurrItem.NewItem(); pCurrLine.Items.Append(pCurrItem); } pCurrItem.TabCount++; } else if (ch == '\r') // CR - line break. // TODO: Two CRs next to one another are treated as </P> rather than <BR><BR> // This should also include the sequence CRLFCRLF. { pCurrLine = new MHTextLine(); theText.Append(pCurrLine); pCurrItem = pCurrItem.NewItem(); pCurrLine.Items.Append(pCurrItem); } else if (ch == 0x1b) // Escape - special codes. { if (i == m_Content.Size) { break; } char code = m_Content.GetAt(i); // The only codes we are interested in are the start and end of colour. // TODO: We may also need "bold" and some hypertext colours. if (code >= 0x40 && code <= 0x5e) // Start code // Start codes are followed by a parameter count and a number of parameter bytes. { if (++i == m_Content.Size) { break; } char paramCount = m_Content.GetAt(i); i++; if (code == 0x43 && paramCount == 4 && i + paramCount <= m_Content.Size) { // Start of colour. if (pCurrItem.Text.Size != 0) { pCurrItem = pCurrItem.NewItem(); pCurrLine.Items.Append(pCurrItem); } pCurrItem.Colour = new MHRgba(m_Content.GetAt(i), m_Content.GetAt(i + 1), m_Content.GetAt(i + 2), 255 - m_Content.GetAt(i + 3)); // Push this colour onto the colour stack. m_ColourStack.Push(pCurrItem.Colour); } else { Logging.Log(Logging.MHLogWarning, "Unknown text escape code " + code); } i += paramCount; // Skip the parameters } else if (code >= 0x60 && code <= 0x7e) // End code. { i++; if (code == 0x63) { if (m_ColourStack.Count > 1) { m_ColourStack.Pop(); // Start a new item since we're using a new colour. if (pCurrItem.Text.Size != 0) { pCurrItem = pCurrItem.NewItem(); pCurrLine.Items.Append(pCurrItem); } // Set the subsequent text in the colour we're using now. pCurrItem.Colour = m_ColourStack.Peek(); } } } } else if (ch <= 0x1f) { // Certain characters including LF and the marker codes between 0x1c and 0x1f are // explicitly intended to be ignored. Include all the other codes. } else // Add to the current text. { int nStart = i - 1; while (i < m_Content.Size && m_Content.GetAt(i) >= 0x20) { i++; } pCurrItem.Text.Append(new MHOctetString(m_Content, nStart, i - nStart)); } } // Set up the initial attributes. int style, size, lineSpace, letterSpace; InterpretAttributes(m_fontAttrs, out style, out size, out lineSpace, out letterSpace); // Create a font with this information. m_pDisplay.SetFont(size, (style & 2) != 0, (style & 1) != 0); // Calculate the layout of each section. for (i = 0; i < theText.Size; i++) { MHTextLine pLine = theText.GetAt(i); pLine.LineWidth = 0; for (int j = 0; j < pLine.Items.Size; j++) { MHTextItem pItem = pLine.Items.GetAt(j); // Set any tabs. for (int k = 0; k < pItem.TabCount; k++) { pLine.LineWidth += TABSTOP - pLine.LineWidth % TABSTOP; } if (pItem.UnicodeLength == 0) { // Convert UTF-8 to Unicode. int s = pItem.Text.Size; pItem.Unicode = pItem.Text.ToString(); pItem.UnicodeLength = pItem.Unicode.Length; } // Fit the text onto the line. int nFullText = pItem.UnicodeLength; // Get the box size and update pItem.m_nUnicode to the number that will fit. Rectangle rect = m_pDisplay.GetBounds(pItem.Unicode, ref nFullText, m_nBoxWidth - pLine.LineWidth); if (nFullText == pItem.UnicodeLength || !m_fTextWrap) { // All the characters fit or we're not wrapping. pItem.Width = rect.Width; pLine.LineWidth += rect.Width; } /* else if (m_fTextWrap) * { // No, we have to word-wrap. * int nTruncated = pItem.UnicodeLength; // Just in case. * // Now remove characters until we find a word-break character. * while (pItem.UnicodeLength > 0 && pItem.Unicode[pItem.UnicodeLength] != ' ') pItem.UnicodeLength--; * // If there are now word-break characters we truncate the text. * if (pItem.UnicodeLength == 0) pItem.UnicodeLength = nTruncated; * // Special case to avoid infinite loop if the box is very narrow. * if (pItem.UnicodeLength == 0) pItem.UnicodeLength = 1; * * // We need to move the text we've cut off this line into a new line. * int nNewWidth = nFullText - pItem.UnicodeLength; * int nNewStart = pItem.UnicodeLength; * // Remove any spaces at the start of the new section. * while (nNewWidth != 0 && pItem.Unicode[nNewStart] == ' ') { nNewStart++; nNewWidth--; } * if (nNewWidth != 0) { * // Create a new line from the extra text. * MHTextLine pNewLine = new MHTextLine(); * theText.InsertAt(pNewLine, i+1); * // The first item on the new line is the rest of the text. * MHTextItem pNewItem = pItem.NewItem(); * pNewLine.Items.Append(pNewItem); * pNewItem.Unicode = pItem.Unicode.Substring(nNewStart, nNewWidth); * pNewItem.UnicodeLength = nNewWidth; * } * // Remove any spaces at the end of the old section. If we don't do that and * // we are centering or right aligning the text we'll get it wrong. * while (pItem.UnicodeLength > 1 && pItem.Unicode[pItem.UnicodeLength - 1] == ' ') pItem.UnicodeLength--; * int uniLength = pItem.UnicodeLength; * rect = m_pDisplay.GetBounds(pItem.Unicode, ref uniLength, 0); * pItem.Width = rect.Width; * pLine.LineWidth += rect.Width; * } */} } // Now output the text. int yOffset = 0; // If there isn't space for all the lines we should drop extra lines. int nNumLines = theText.Size; do { if (m_VertJ == End) { yOffset = m_nBoxHeight - nNumLines * lineSpace; } else if (m_VertJ == Centre) { yOffset = (m_nBoxHeight - nNumLines * lineSpace) / 2; } if (yOffset < 0) { nNumLines--; } } while (yOffset < 0); for (i = 0; i < nNumLines; i++) { MHTextLine pLine = theText.GetAt(i); int xOffset = 0; if (m_HorizJ == End) { xOffset = m_nBoxWidth - pLine.LineWidth; } else if (m_HorizJ == Centre) { xOffset = (m_nBoxWidth - pLine.LineWidth) / 2; } //ASSERT(xOffset >= 0); for (int j = 0; j < pLine.Items.Size; j++) { MHTextItem pItem = pLine.Items.GetAt(j); // Tab across if necessary. for (int k = 0; k < pItem.TabCount; k++) { xOffset += TABSTOP - xOffset % TABSTOP; } if (pItem.Unicode.Length != 0) // We may have blank lines. { m_pDisplay.AddText(xOffset, yOffset, // Jas removed this cos it doesn't make sense yOffset + lineSpace pItem.Unicode.Substring(0, pItem.UnicodeLength), pItem.Colour); } xOffset += pItem.Width; } yOffset += lineSpace; if (yOffset + lineSpace > m_nBoxHeight) { break; } } }