inline void wxCheckSetFont(wxDC& dc, const wxFont& font)
{
+#if 0
const wxFont& font1 = dc.GetFont();
if (font1.IsOk() && font.IsOk())
{
font1.GetStyle() == font.GetStyle() &&
font1.GetWeight() == font.GetWeight() &&
font1.GetUnderlined() == font.GetUnderlined() &&
+ font1.GetFamily() == font.GetFamily() &&
font1.GetFaceName() == font.GetFaceName())
return;
}
+#endif
dc.SetFont(font);
}
while (node)
{
wxRichTextObject* child = node->GetData();
- if (!child->GetRange().IsOutside(range))
+ if (range == wxRICHTEXT_ALL || !child->GetRange().IsOutside(range))
{
wxRichTextCompositeObject* composite = wxDynamicCast(child, wxRichTextCompositeObject);
if (composite)
// we only want the paragraphs to hold this character style, then we _don't_ want to
// apply the character style. So we need to be able to choose.
- // if (!paragraphStyle && characterStyle && range.GetStart() != newPara->GetRange().GetEnd())
- if (!parasOnly && characterStyle && range.GetStart() != newPara->GetRange().GetEnd())
+ if (!parasOnly && (characterStyle|charactersOnly) && range.GetStart() != newPara->GetRange().GetEnd())
{
wxRichTextRange childRange(range);
childRange.LimitTo(newPara->GetRange());
/// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of
/// content.
-bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttr& currentStyle, const wxTextAttr& style, long& multipleStyleAttributes, int& multipleTextEffectAttributes)
+bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttr& currentStyle, const wxTextAttr& style, long& multipleStyleAttributes, int& multipleTextEffectAttributes, int& absentStyleAttributes, int& absentTextEffectAttributes)
{
+ absentStyleAttributes |= (~style.GetFlags() & wxTEXT_ATTR_ALL);
+ absentTextEffectAttributes |= (~style.GetTextEffectFlags() & 0xFFFF);
+
if (style.HasFont())
{
- if (style.HasFontSize() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_SIZE))
+ if (style.HasFontSize() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_SIZE))
{
if (currentStyle.HasFontSize())
{
}
}
- if (style.HasFontItalic() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_ITALIC))
+ if (style.HasFontItalic() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_ITALIC))
{
if (currentStyle.HasFontItalic())
{
}
}
- if (style.HasFontWeight() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_WEIGHT))
+ if (style.HasFontFamily() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_FAMILY))
+ {
+ if (currentStyle.HasFontFamily())
+ {
+ if (currentStyle.GetFontFamily() != style.GetFontFamily())
+ {
+ // Clash of style - mark as such
+ multipleStyleAttributes |= wxTEXT_ATTR_FONT_FAMILY;
+ currentStyle.SetFlags(currentStyle.GetFlags() & ~wxTEXT_ATTR_FONT_FAMILY);
+ }
+ }
+ else
+ {
+ currentStyle.SetFontFamily(style.GetFontFamily());
+ }
+ }
+
+ if (style.HasFontWeight() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_WEIGHT))
{
if (currentStyle.HasFontWeight())
{
}
}
- if (style.HasFontFaceName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_FACE))
+ if (style.HasFontFaceName() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_FACE))
{
if (currentStyle.HasFontFaceName())
{
}
}
- if (style.HasFontUnderlined() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_FONT_UNDERLINE))
+ if (style.HasFontUnderlined() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_FONT_UNDERLINE))
{
if (currentStyle.HasFontUnderlined())
{
}
}
- if (style.HasTextColour() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_TEXT_COLOUR))
+ if (style.HasTextColour() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_TEXT_COLOUR))
{
if (currentStyle.HasTextColour())
{
currentStyle.SetTextColour(style.GetTextColour());
}
- if (style.HasBackgroundColour() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BACKGROUND_COLOUR))
+ if (style.HasBackgroundColour() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_BACKGROUND_COLOUR))
{
if (currentStyle.HasBackgroundColour())
{
currentStyle.SetBackgroundColour(style.GetBackgroundColour());
}
- if (style.HasAlignment() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_ALIGNMENT))
+ if (style.HasAlignment() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_ALIGNMENT))
{
if (currentStyle.HasAlignment())
{
currentStyle.SetAlignment(style.GetAlignment());
}
- if (style.HasTabs() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_TABS))
+ if (style.HasTabs() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_TABS))
{
if (currentStyle.HasTabs())
{
currentStyle.SetTabs(style.GetTabs());
}
- if (style.HasLeftIndent() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_LEFT_INDENT))
+ if (style.HasLeftIndent() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_LEFT_INDENT))
{
if (currentStyle.HasLeftIndent())
{
currentStyle.SetLeftIndent(style.GetLeftIndent(), style.GetLeftSubIndent());
}
- if (style.HasRightIndent() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_RIGHT_INDENT))
+ if (style.HasRightIndent() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_RIGHT_INDENT))
{
if (currentStyle.HasRightIndent())
{
currentStyle.SetRightIndent(style.GetRightIndent());
}
- if (style.HasParagraphSpacingAfter() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_PARA_SPACING_AFTER))
+ if (style.HasParagraphSpacingAfter() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_PARA_SPACING_AFTER))
{
if (currentStyle.HasParagraphSpacingAfter())
{
currentStyle.SetParagraphSpacingAfter(style.GetParagraphSpacingAfter());
}
- if (style.HasParagraphSpacingBefore() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_PARA_SPACING_BEFORE))
+ if (style.HasParagraphSpacingBefore() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_PARA_SPACING_BEFORE))
{
if (currentStyle.HasParagraphSpacingBefore())
{
currentStyle.SetParagraphSpacingBefore(style.GetParagraphSpacingBefore());
}
- if (style.HasLineSpacing() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_LINE_SPACING))
+ if (style.HasLineSpacing() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_LINE_SPACING))
{
if (currentStyle.HasLineSpacing())
{
currentStyle.SetLineSpacing(style.GetLineSpacing());
}
- if (style.HasCharacterStyleName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_CHARACTER_STYLE_NAME))
+ if (style.HasCharacterStyleName() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_CHARACTER_STYLE_NAME))
{
if (currentStyle.HasCharacterStyleName())
{
currentStyle.SetCharacterStyleName(style.GetCharacterStyleName());
}
- if (style.HasParagraphStyleName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_PARAGRAPH_STYLE_NAME))
+ if (style.HasParagraphStyleName() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_PARAGRAPH_STYLE_NAME))
{
if (currentStyle.HasParagraphStyleName())
{
currentStyle.SetParagraphStyleName(style.GetParagraphStyleName());
}
- if (style.HasListStyleName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_LIST_STYLE_NAME))
+ if (style.HasListStyleName() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_LIST_STYLE_NAME))
{
if (currentStyle.HasListStyleName())
{
currentStyle.SetListStyleName(style.GetListStyleName());
}
- if (style.HasBulletStyle() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BULLET_STYLE))
+ if (style.HasBulletStyle() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_BULLET_STYLE))
{
if (currentStyle.HasBulletStyle())
{
currentStyle.SetBulletStyle(style.GetBulletStyle());
}
- if (style.HasBulletNumber() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BULLET_NUMBER))
+ if (style.HasBulletNumber() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_BULLET_NUMBER))
{
if (currentStyle.HasBulletNumber())
{
currentStyle.SetBulletNumber(style.GetBulletNumber());
}
- if (style.HasBulletText() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BULLET_TEXT))
+ if (style.HasBulletText() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_BULLET_TEXT))
{
if (currentStyle.HasBulletText())
{
}
}
- if (style.HasBulletName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BULLET_NAME))
+ if (style.HasBulletName() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_BULLET_NAME))
{
if (currentStyle.HasBulletName())
{
}
}
- if (style.HasURL() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_URL))
+ if (style.HasURL() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_URL))
{
if (currentStyle.HasURL())
{
}
}
- if (style.HasTextEffects() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_EFFECTS))
+ if (style.HasTextEffects() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_EFFECTS))
{
if (currentStyle.HasTextEffects())
{
// We need to find the bits in the new style that are different:
// just look at those bits that are specified by the new style.
+ // We need to remove the bits and flags that are not common between current style
+ // and new style. In so doing we need to take account of the styles absent from one or more of the
+ // previous styles.
+
int currentRelevantTextEffects = currentStyle.GetTextEffects() & style.GetTextEffectFlags();
int newRelevantTextEffects = style.GetTextEffects() & style.GetTextEffectFlags();
currentStyle.SetTextEffects(style.GetTextEffects());
currentStyle.SetTextEffectFlags(style.GetTextEffectFlags());
}
+
+ // Mask out the flags and values that cannot be common because they were absent in one or more objecrs
+ // that we've looked at so far
+ currentStyle.SetTextEffects(currentStyle.GetTextEffects() & ~absentTextEffectAttributes);
+ currentStyle.SetTextEffectFlags(currentStyle.GetTextEffectFlags() & ~absentTextEffectAttributes);
+
+ if (currentStyle.GetTextEffectFlags() == 0)
+ currentStyle.SetFlags(currentStyle.GetFlags() & ~wxTEXT_ATTR_EFFECTS);
}
- if (style.HasOutlineLevel() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_OUTLINE_LEVEL))
+ if (style.HasOutlineLevel() && !wxHasStyle(multipleStyleAttributes|absentStyleAttributes, wxTEXT_ATTR_OUTLINE_LEVEL))
{
if (currentStyle.HasOutlineLevel())
{
long multipleStyleAttributes = 0;
int multipleTextEffectAttributes = 0;
+ int absentStyleAttributesPara = 0;
+ int absentStyleAttributesChar = 0;
+ int absentTextEffectAttributesPara = 0;
+ int absentTextEffectAttributesChar = 0;
+
wxRichTextObjectList::compatibility_iterator node = GetChildren().GetFirst();
while (node)
{
{
wxTextAttr paraStyle = para->GetCombinedAttributes();
- CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes);
+ CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes, absentStyleAttributesPara, absentTextEffectAttributesPara);
}
else
{
// First collect paragraph attributes only
wxTextAttr paraStyle = para->GetCombinedAttributes();
paraStyle.SetFlags(paraStyle.GetFlags() & wxTEXT_ATTR_PARAGRAPH);
- CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes);
+ CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes, absentStyleAttributesPara, absentTextEffectAttributesPara);
wxRichTextObjectList::compatibility_iterator childNode = para->GetChildren().GetFirst();
// Now collect character attributes only
childStyle.SetFlags(childStyle.GetFlags() & wxTEXT_ATTR_CHARACTER);
- CollectStyle(style, childStyle, multipleStyleAttributes, multipleTextEffectAttributes);
+ CollectStyle(style, childStyle, multipleStyleAttributes, multipleTextEffectAttributes, absentStyleAttributesChar, absentTextEffectAttributesChar);
}
childNode = childNode->GetNext();
}
// Get line height from first line, if any
- wxRichTextLine* line = m_cachedLines.GetFirst() ? (wxRichTextLine* ) m_cachedLines.GetFirst()->GetData() : (wxRichTextLine*) NULL;
+ wxRichTextLine* line = m_cachedLines.GetFirst() ? (wxRichTextLine* ) m_cachedLines.GetFirst()->GetData() : NULL;
wxPoint linePos;
int lineHeight wxDUMMY_INITIALIZE(0);
wxSize actualSize;
wxRichTextRange actualRange(lastCompletedEndPos+1, wrapPosition);
+ /// Use previous descent, not the wrapping descent we just found, since this may be too big
+ /// for the fragment we're about to add.
+ childDescent = maxDescent;
+
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
// Get height only, then the width using the partial extents
GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY);
ClearUnusedLines(lineCount);
// Apply styles to wrapped lines
- ApplyParagraphStyle(attr, rect);
+ ApplyParagraphStyle(attr, rect, dc);
SetCachedSize(wxSize(maxWidth, currentPosition.y + spaceBeforePara + spaceAfterPara));
}
/// Apply paragraph styles, such as centering, to wrapped lines
-void wxRichTextParagraph::ApplyParagraphStyle(const wxTextAttr& attr, const wxRect& rect)
+void wxRichTextParagraph::ApplyParagraphStyle(const wxTextAttr& attr, const wxRect& rect, wxDC& dc)
{
if (!attr.HasAlignment())
return;
// centering, right-justification
if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
{
- pos.x = (rect.GetWidth() - size.x)/2 + pos.x;
+ int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
+ pos.x = (rect.GetWidth() - (pos.x - rect.x) - rightIndent - size.x)/2 + pos.x;
+ // Lines are relative to the paragraph position
+ pos.x -= GetPosition().x;
line->SetPosition(pos);
}
else if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
{
- pos.x = pos.x + rect.GetWidth() - size.x;
+ int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent());
+ pos.x = rect.x + rect.GetWidth() - size.x - rightIndent;
+ // Lines are relative to the paragraph position
+ pos.x -= GetPosition().x;
line->SetPosition(pos);
}
text += textObj->GetTextForRange(range);
}
else
- return true;
+ {
+ text += wxT(" ");
+ }
}
node = node->GetNext();
text = textObj->GetTextForRange(range) + text;
}
else
- return true;
+ {
+ text = wxT(" ") + text;
+ }
}
node = node->GetPrevious();
widthBefore = 0;
size_t i;
- for (i = (size_t) range.GetStart(); i < (size_t) range.GetEnd(); i++)
+ for (i = (size_t) range.GetStart(); i <= (size_t) range.GetEnd(); i++)
{
int widthFromStartOfThisRange = (*partialExtents)[i - GetRange().GetStart()] - widthBefore;
{
if (para && para->GetRange().GetEnd() == pos)
pos1 ++;
+
+ // Now see if we need to number the paragraph.
if (newPara->GetAttributes().HasBulletNumber())
- newPara->GetAttributes().SetBulletNumber(newPara->GetAttributes().GetBulletNumber()+1);
+ {
+ wxRichTextAttr numberingAttr;
+ if (FindNextParagraphNumber(para, numberingAttr))
+ wxRichTextApplyStyle(newPara->GetAttributes(), (const wxRichTextAttr&) numberingAttr);
+ }
}
action->SetPosition(pos);
}
}
}
+
+ // Also apply list style if present
+ if (lookUpNewParaStyle && !para->GetAttributes().GetListStyleName().IsEmpty() && GetStyleSheet())
+ {
+ wxRichTextListStyleDefinition* listDef = GetStyleSheet()->FindListStyle(para->GetAttributes().GetListStyleName());
+ if (listDef)
+ {
+ int thisIndent = para->GetAttributes().GetLeftIndent();
+ int thisLevel = para->GetAttributes().HasOutlineLevel() ? para->GetAttributes().GetOutlineLevel() : listDef->FindLevelForIndent(thisIndent);
+
+ // Apply the overall list style, and item style for this level
+ wxRichTextAttr listStyle(listDef->GetCombinedStyleForLevel(thisLevel, GetStyleSheet()));
+ wxRichTextApplyStyle(attr, listStyle);
+ attr.SetOutlineLevel(thisLevel);
+ if (para->GetAttributes().HasBulletNumber())
+ attr.SetBulletNumber(para->GetAttributes().GetBulletNumber());
+ }
+ }
+
if (!foundAttributes)
{
attr = para->GetAttributes();
attr.SetFlags(flags);
}
- // Now see if we need to number the paragraph.
- if (attr.HasBulletStyle())
- {
- wxTextAttr numberingAttr;
- if (FindNextParagraphNumber(para, numberingAttr))
- wxRichTextApplyStyle(attr, (const wxTextAttr&) numberingAttr);
- }
-
return attr;
}
else
bool wxRichTextBuffer::BeginBold()
{
wxTextAttr attr;
- attr.SetFontWeight(wxBOLD);
+ attr.SetFontWeight(wxFONTWEIGHT_BOLD);
return BeginStyle(attr);
}
bool wxRichTextBuffer::BeginItalic()
{
wxTextAttr attr;
- attr.SetFontStyle(wxITALIC);
+ attr.SetFontStyle(wxFONTSTYLE_ITALIC);
return BeginStyle(attr);
}
else if (!filename.IsEmpty())
{
wxString path, file, ext;
- wxSplitPath(filename, & path, & file, & ext);
+ wxFileName::SplitPath(filename, & path, & file, & ext);
return FindHandler(ext, imageType);
}
else
if (action->GetNewParagraphs().GetChildCount() == 1)
action->GetNewParagraphs().SetPartialParagraph(true);
- action->SetPosition(position);
+ action->SetPosition(position+1);
// Set the range we'll need to delete in Undo
- action->SetRange(wxRichTextRange(position, position));
+ action->SetRange(wxRichTextRange(position+1, position+1));
SubmitAction(action);
/// Make block from the wxImage
bool wxRichTextImage::MakeBlock()
{
- if (m_imageBlock.GetImageType() == wxBITMAP_TYPE_ANY || m_imageBlock.GetImageType() == -1)
- m_imageBlock.SetImageType(wxBITMAP_TYPE_PNG);
+ wxBitmapType type = m_imageBlock.GetImageType();
+ if ( type == wxBITMAP_TYPE_ANY || type == wxBITMAP_TYPE_INVALID )
+ m_imageBlock.SetImageType(type = wxBITMAP_TYPE_PNG);
- m_imageBlock.MakeImageBlock(m_image, m_imageBlock.GetImageType());
+ m_imageBlock.MakeImageBlock(m_image, type);
return m_imageBlock.Ok();
}
bool wxRichTextFileHandler::CanHandle(const wxString& filename) const
{
wxString path, file, ext;
- wxSplitPath(filename, & path, & file, & ext);
+ wxFileName::SplitPath(filename, & path, & file, & ext);
return (ext.Lower() == GetExtension());
}
wxString filenameToRead(filename);
bool removeFile = false;
- if (imageType == -1)
+ if (imageType == wxBITMAP_TYPE_INVALID)
return false; // Could not determine image type
if ((imageType != wxBITMAP_TYPE_JPEG) && convertToJPEG)
{
- wxString tempFile;
- bool success = wxGetTempFileName(_("image"), tempFile) ;
-
- wxASSERT(success);
+ wxString tempFile =
+ wxFileName::CreateTempFileName(_("image"));
- wxUnusedVar(success);
+ wxASSERT(!tempFile.IsEmpty());
image.SaveFile(tempFile, wxBITMAP_TYPE_JPEG);
filenameToRead = tempFile;
m_imageType = imageType;
image.SetOption(wxT("quality"), quality);
- if (imageType == -1)
+ if (imageType == wxBITMAP_TYPE_INVALID)
return false; // Could not determine image type
- wxString tempFile;
- bool success = wxGetTempFileName(_("image"), tempFile) ;
-
- wxASSERT(success);
- wxUnusedVar(success);
+ wxString tempFile = wxFileName::CreateTempFileName(_("image")) ;
+ wxASSERT(!tempFile.IsEmpty());
if (!image.SaveFile(tempFile, m_imageType))
{
wxMemoryInputStream mstream(m_data, m_dataSize);
bool success = image.LoadFile(mstream, GetImageType());
#else
- wxString tempFile;
- bool success = wxGetTempFileName(_("image"), tempFile) ;
- wxASSERT(success);
+ wxString tempFile = wxFileName::CreateTempFileName(_("image"));
+ wxASSERT(!tempFile.IsEmpty());
if (!WriteBlock(tempFile, m_data, m_dataSize))
{
if (m_data)
delete[] m_data;
- wxChar str[2];
+ // create a null terminated temporary string:
+ char str[3];
+ str[2] = '\0';
+
m_data = new unsigned char[dataSize];
int i;
for (i = 0; i < dataSize; i ++)