//Look up the IAccessible2 objects at the positions of the embedded object chars\r
//Add the text and IA2 objects in order to a vector for later adding to the buffer\r
if(paccHypertext&&IA2Text!=NULL&&IA2TextLength>0&&!IA2TextIsUnneededSpace) {\r
- LOG_DEBUG(L"scanning text for embedded object chars");\r
- int textStart=-1;\r
- wchar_t* tempText=NULL;\r
- for(int i=0;i<IA2TextLength;++i) {\r
- LOG_DEBUG(L"offset "<<i);\r
- if(IA2Text[i]!=0xfffc) { //is not an embeded object char\r
- LOG_DEBUG(L"normal char");\r
- if(tempText==NULL) {\r
- textStart=i;\r
- LOG_DEBUG(L"allocating new tempText memory to hold "<<((IA2TextLength+1)-i)<<L" chars");\r
- tempText=(wchar_t*)malloc(sizeof(wchar_t)*((IA2TextLength+1)-i));\r
- if(tempText==NULL) {\r
- LOG_DEBUG(L"Error allocating tempText memory");\r
- return NULL;\r
- }\r
+ LOG_DEBUG(L"scanning text");\r
+ int chunkStart=0;\r
+ long attribsStart = 0;\r
+ long attribsEnd = 0;\r
+ map<wstring,wstring> textAttribs;\r
+ for(int i=0;;++i) {\r
+ if(i!=chunkStart&&(i==IA2TextLength||i==attribsEnd||IA2Text[i]==0xfffc)) {\r
+ // We've reached the end of the current chunk of text.\r
+ // (A chunk ends at the end of the text, at the end of an attributes run\r
+ // or at an embedded object char.)\r
+ // Add the chunk to the buffer.\r
+ LOG_DEBUG("Adding text chunk, start="<<chunkStart<<" end="<<i);\r
+ if((tempNode=buffer->addTextFieldNode(parentNode,previousNode,wstring(IA2Text+chunkStart,i-chunkStart)))!=NULL) {\r
+ previousNode=tempNode;\r
+ // Add text attributes.\r
+ for(map<wstring,wstring>::const_iterator it=textAttribs.begin();it!=textAttribs.end();++it)\r
+ previousNode->addAttribute(it->first,it->second);\r
}\r
- tempText[i-textStart]=IA2Text[i];\r
- } else { //is an embedded object char\r
- LOG_DEBUG(L"is an embedded object char");\r
- if(tempText!=NULL) {\r
- LOG_DEBUG(L"there is tempText, terminate it with NULL");\r
- tempText[i-textStart]=L'\0';\r
- LOG_DEBUG(L"adding tempText of length "<<(i-textStart)+1<<L" to buffer");\r
- if((tempNode=buffer->addTextFieldNode(parentNode,previousNode,tempText))!=NULL) {\r
- previousNode=tempNode;\r
+ }\r
+ if(i==IA2TextLength)\r
+ break;\r
+ if(i==attribsEnd) {\r
+ // We've hit the end of the last attributes run and thus the start of the next.\r
+ textAttribs.clear();\r
+ chunkStart=i;\r
+ BSTR attribsStr;\r
+ if(paccText->get_attributes(attribsEnd,&attribsStart,&attribsEnd,&attribsStr)==S_OK) {\r
+ LOG_DEBUG("Start of new attributes run at "<<i);\r
+ if(attribsStr) {\r
+ IA2AttribsToMap(attribsStr,textAttribs);\r
+ SysFreeString(attribsStr);\r
}\r
- free(tempText);\r
- tempText=NULL;\r
+ } else {\r
+ // If attributes fails, assume it'll fail for the entire text.\r
+ attribsEnd=IA2TextLength;\r
}\r
+ }\r
+ if(IA2Text[i]==0xfffc) {\r
+ // Embedded object char.\r
+ LOG_DEBUG(L"embedded object char at "<<i);\r
+ // The next chunk of text shouldn't include this char.\r
+ chunkStart=i+1;\r
LOG_DEBUG(L"get hyperlinkIndex with IAccessibleHypertext::get_hyperlinkIndex and offset "<<i);\r
int hyperlinkIndex;\r
if((res=paccHypertext->get_hyperlinkIndex(i,(long*)(&hyperlinkIndex)))!=S_OK) {\r
}\r
}\r
LOG_DEBUG(L"End of scan");\r
- if(tempText!=NULL) {\r
- LOG_DEBUG(L"some tempText left, terminate with NULL");\r
- tempText[IA2TextLength-textStart]=L'\0';\r
- LOG_DEBUG(L"add tempText of length "<<(IA2TextLength-textStart)+1<<L" to buffer");\r
- previousNode=buffer->addTextFieldNode(parentNode,previousNode,tempText);\r
- free(tempText);\r
- tempText=NULL;\r
- }\r
} else if(IA2TextLength>0&&!IA2TextIsUnneededSpace) {\r
LOG_DEBUG(L"add IA2Text to childVector");\r
if((tempNode=buffer->addTextFieldNode(parentNode,previousNode,IA2Text))!=NULL) {\r