ReactOS  0.4.14-dev-606-g14ebc0b
richole.c
Go to the documentation of this file.
1 /*
2  * RichEdit GUIDs and OLE interface
3  *
4  * Copyright 2004 by Krzysztof Foltman
5  * Copyright 2004 Aric Stewart
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 
24 #define NONAMELESSUNION
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "richole.h"
33 #include "editor.h"
34 #include "richedit.h"
35 #include "tom.h"
36 #include "wine/debug.h"
37 
39 
40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
41 
42 #include "initguid.h"
43 
44 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
45 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
46 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
48 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
49 DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
50 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 
55 static ITypeLib *typelib;
56 
57 enum tid_t {
65 };
66 
67 static const IID * const tid_ids[] =
68 {
69  &IID_NULL,
70  &IID_ITextDocument,
71  &IID_ITextRange,
72  &IID_ITextSelection,
73  &IID_ITextFont,
74  &IID_ITextPara,
75 };
77 
78 static HRESULT load_typelib(void)
79 {
80  ITypeLib *tl;
81  HRESULT hr;
82 
83  hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
84  if (FAILED(hr)) {
85  ERR("LoadRegTypeLib failed: %08x\n", hr);
86  return hr;
87  }
88 
90  ITypeLib_Release(tl);
91  return hr;
92 }
93 
94 void release_typelib(void)
95 {
96  unsigned i;
97 
98  if (!typelib)
99  return;
100 
101  for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
102  if (typeinfos[i])
103  ITypeInfo_Release(typeinfos[i]);
104 
105  ITypeLib_Release(typelib);
106 }
107 
109 {
110  HRESULT hr;
111 
112  if (!typelib)
113  hr = load_typelib();
114  if (!typelib)
115  return hr;
116 
117  if (!typeinfos[tid])
118  {
119  ITypeInfo *ti;
120 
121  hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
122  if (FAILED(hr))
123  {
124  ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
125  return hr;
126  }
127 
129  ITypeInfo_Release(ti);
130  }
131 
132  *typeinfo = typeinfos[tid];
133  return S_OK;
134 }
135 
136 /* private IID used to get back IRichEditOleImpl pointer */
137 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 
142 
170 };
171 
172 static const DWORD textfont_prop_masks[][2] = {
174  { CFM_ANIMATION },
176  { CFM_BOLD, CFE_BOLD },
177  { CFM_EMBOSS, CFE_EMBOSS },
179  { CFM_HIDDEN, CFE_HIDDEN },
181  { CFM_ITALIC, CFE_ITALIC },
182  { CFM_KERNING },
183  { CFM_LCID },
184  { CFM_FACE },
186  { CFM_OFFSET },
188  { CFM_SHADOW, CFE_SHADOW },
189  { CFM_SIZE },
191  { CFM_SPACING },
196  { CFM_WEIGHT }
197 };
198 
199 typedef union {
204 
207 };
208 
209 typedef struct IRichEditOleImpl {
215 
218 
219  struct list rangelist;
222 
223 struct reole_child {
224  struct list entry;
226 };
227 
233 };
234 
238 
240 };
241 
242 typedef struct ITextFontImpl {
245 
250 } ITextFontImpl;
251 
252 typedef struct ITextParaImpl {
255 
257 } ITextParaImpl;
258 
264 };
265 
267 {
268  return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
269 }
270 
272 {
273  return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface);
274 }
275 
277 {
278  return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
279 }
280 
282 {
283  return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
284 }
285 
287 {
288  return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
289 }
290 
292 {
293  return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
294 }
295 
297 {
298  return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
299 }
300 
302 {
303  return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
304 }
305 
309 
311 {
312  if (!length)
313  return E_INVALIDARG;
314 
315  *length = ME_GetTextLength(editor) + 1;
316  return S_OK;
317 }
318 
320 {
322 
324  switch (op)
325  {
326  case RANGE_UPDATE_DELETE:
327  /* range fully covered by deleted range - collapse to insertion point */
328  if (range->start >= start && range->end <= end)
329  range->start = range->end = start;
330  /* deleted range cuts from the right */
331  else if (range->start < start && range->end <= end)
332  range->end = start;
333  /* deleted range cuts from the left */
334  else if (range->start >= start && range->end > end) {
335  range->start = start;
336  range->end -= end - start;
337  }
338  /* deleted range cuts within */
339  else
340  range->end -= end - start;
341  break;
342  default:
343  FIXME("unknown update op, %d\n", op);
344  }
345  }
346 }
347 
350 {
351  switch (propid)
352  {
353  case FONT_ALLCAPS:
354  case FONT_ANIMATION:
355  case FONT_BACKCOLOR:
356  case FONT_BOLD:
357  case FONT_EMBOSS:
358  case FONT_FORECOLOR:
359  case FONT_HIDDEN:
360  case FONT_ENGRAVE:
361  case FONT_ITALIC:
362  case FONT_KERNING:
363  case FONT_LANGID:
364  case FONT_OUTLINE:
365  case FONT_PROTECTED:
366  case FONT_SHADOW:
367  case FONT_SMALLCAPS:
368  case FONT_STRIKETHROUGH:
369  case FONT_SUBSCRIPT:
370  case FONT_SUPERSCRIPT:
371  case FONT_UNDERLINE:
372  case FONT_WEIGHT:
373  return left->l == right->l;
374  case FONT_NAME:
375  return !wcscmp(left->str, right->str);
376  case FONT_POSITION:
377  case FONT_SIZE:
378  case FONT_SPACING:
379  return left->f == right->f;
380  default:
381  FIXME("unhandled font property %d\n", propid);
382  return FALSE;
383  }
384 }
385 
387 {
388  switch (propid)
389  {
390  case FONT_ALLCAPS:
391  case FONT_ANIMATION:
392  case FONT_BACKCOLOR:
393  case FONT_BOLD:
394  case FONT_EMBOSS:
395  case FONT_FORECOLOR:
396  case FONT_HIDDEN:
397  case FONT_ENGRAVE:
398  case FONT_ITALIC:
399  case FONT_KERNING:
400  case FONT_LANGID:
401  case FONT_OUTLINE:
402  case FONT_PROTECTED:
403  case FONT_SHADOW:
404  case FONT_SMALLCAPS:
405  case FONT_STRIKETHROUGH:
406  case FONT_SUBSCRIPT:
407  case FONT_SUPERSCRIPT:
408  case FONT_UNDERLINE:
409  case FONT_WEIGHT:
410  v->l = tomUndefined;
411  return;
412  case FONT_NAME:
413  v->str = NULL;
414  return;
415  case FONT_POSITION:
416  case FONT_SIZE:
417  case FONT_SPACING:
418  v->f = tomUndefined;
419  return;
420  default:
421  FIXME("unhandled font property %d\n", propid);
422  v->l = tomUndefined;
423  return;
424  }
425 }
426 
428 {
429  return value * 72.0 / 1440;
430 }
431 
433 {
434  return value * 1440 / 72.0;
435 }
436 
439 {
440  ME_Cursor from, to;
442 
443  memset(&fmt, 0, sizeof(fmt));
444  fmt.cbSize = sizeof(fmt);
445  fmt.dwMask = textfont_prop_masks[propid][0];
446 
448  to = from;
450  ME_GetCharFormat(reole->editor, &from, &to, &fmt);
451 
452  switch (propid)
453  {
454  case FONT_ALLCAPS:
455  case FONT_BOLD:
456  case FONT_EMBOSS:
457  case FONT_HIDDEN:
458  case FONT_ENGRAVE:
459  case FONT_ITALIC:
460  case FONT_OUTLINE:
461  case FONT_PROTECTED:
462  case FONT_SHADOW:
463  case FONT_SMALLCAPS:
464  case FONT_STRIKETHROUGH:
465  case FONT_SUBSCRIPT:
466  case FONT_SUPERSCRIPT:
467  case FONT_UNDERLINE:
468  value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
469  break;
470  case FONT_ANIMATION:
471  value->l = fmt.bAnimation;
472  break;
473  case FONT_BACKCOLOR:
474  value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
475  break;
476  case FONT_FORECOLOR:
477  value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
478  break;
479  case FONT_KERNING:
480  value->f = twips_to_points(fmt.wKerning);
481  break;
482  case FONT_LANGID:
483  value->l = fmt.lcid;
484  break;
485  case FONT_NAME:
486  /* this case is used exclusively by GetName() */
487  value->str = SysAllocString(fmt.szFaceName);
488  if (!value->str)
489  return E_OUTOFMEMORY;
490  break;
491  case FONT_POSITION:
492  value->f = twips_to_points(fmt.yOffset);
493  break;
494  case FONT_SIZE:
495  value->f = twips_to_points(fmt.yHeight);
496  break;
497  case FONT_SPACING:
498  value->f = fmt.sSpacing;
499  break;
500  case FONT_WEIGHT:
501  value->l = fmt.wWeight;
502  break;
503  default:
504  FIXME("unhandled font property %d\n", propid);
505  return E_FAIL;
506  }
507 
508  return S_OK;
509 }
510 
512 {
514  ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
515  return reole;
516 }
517 
519 {
521  HRESULT hr;
522  LONG value;
523  BSTR str;
524  FLOAT f;
525 
526 #define CHARFORMAT_SET_B_FIELD(mask, value) \
527  if (hr == S_OK && value != tomUndefined) { \
528  fmt.dwMask |= CFM_##mask; \
529  if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
530  } \
531 
532  /* fill format data from font */
533  memset(&fmt, 0, sizeof(fmt));
534  fmt.cbSize = sizeof(fmt);
535 
537  hr = ITextFont_GetAllCaps(font, &value);
538  CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
539 
541  hr = ITextFont_GetBold(font, &value);
543 
545  hr = ITextFont_GetEmboss(font, &value);
546  CHARFORMAT_SET_B_FIELD(EMBOSS, value);
547 
549  hr = ITextFont_GetHidden(font, &value);
551 
553  hr = ITextFont_GetEngrave(font, &value);
554  CHARFORMAT_SET_B_FIELD(IMPRINT, value);
555 
557  hr = ITextFont_GetItalic(font, &value);
559 
561  hr = ITextFont_GetOutline(font, &value);
562  CHARFORMAT_SET_B_FIELD(OUTLINE, value);
563 
565  hr = ITextFont_GetProtected(font, &value);
566  CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567 
569  hr = ITextFont_GetShadow(font, &value);
570  CHARFORMAT_SET_B_FIELD(SHADOW, value);
571 
573  hr = ITextFont_GetSmallCaps(font, &value);
574  CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575 
577  hr = ITextFont_GetStrikeThrough(font, &value);
578  CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579 
581  hr = ITextFont_GetSubscript(font, &value);
583 
585  hr = ITextFont_GetSuperscript(font, &value);
586  CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587 
589  hr = ITextFont_GetUnderline(font, &value);
590  CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591 
592 #undef CHARFORMAT_SET_B_FIELD
593 
595  hr = ITextFont_GetAnimation(font, &value);
596  if (hr == S_OK && value != tomUndefined) {
597  fmt.dwMask |= CFM_ANIMATION;
598  fmt.bAnimation = value;
599  }
600 
602  hr = ITextFont_GetBackColor(font, &value);
603  if (hr == S_OK && value != tomUndefined) {
604  fmt.dwMask |= CFM_BACKCOLOR;
605  if (value == tomAutoColor)
606  fmt.dwEffects |= CFE_AUTOBACKCOLOR;
607  else
608  fmt.crBackColor = value;
609  }
610 
612  hr = ITextFont_GetForeColor(font, &value);
613  if (hr == S_OK && value != tomUndefined) {
614  fmt.dwMask |= CFM_COLOR;
615  if (value == tomAutoColor)
616  fmt.dwEffects |= CFE_AUTOCOLOR;
617  else
618  fmt.crTextColor = value;
619  }
620 
622  hr = ITextFont_GetKerning(font, &f);
623  if (hr == S_OK && f != tomUndefined) {
624  fmt.dwMask |= CFM_KERNING;
625  fmt.wKerning = points_to_twips(f);
626  }
627 
629  hr = ITextFont_GetLanguageID(font, &value);
630  if (hr == S_OK && value != tomUndefined) {
631  fmt.dwMask |= CFM_LCID;
632  fmt.lcid = value;
633  }
634 
635  if (ITextFont_GetName(font, &str) == S_OK) {
636  fmt.dwMask |= CFM_FACE;
637  lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
639  }
640 
641  hr = ITextFont_GetPosition(font, &f);
642  if (hr == S_OK && f != tomUndefined) {
643  fmt.dwMask |= CFM_OFFSET;
644  fmt.yOffset = points_to_twips(f);
645  }
646 
647  hr = ITextFont_GetSize(font, &f);
648  if (hr == S_OK && f != tomUndefined) {
649  fmt.dwMask |= CFM_SIZE;
650  fmt.yHeight = points_to_twips(f);
651  }
652 
653  hr = ITextFont_GetSpacing(font, &f);
654  if (hr == S_OK && f != tomUndefined) {
655  fmt.dwMask |= CFM_SPACING;
656  fmt.sSpacing = f;
657  }
658 
659  hr = ITextFont_GetWeight(font, &value);
660  if (hr == S_OK && value != tomUndefined) {
661  fmt.dwMask |= CFM_WEIGHT;
662  fmt.wWeight = value;
663  }
664 
665  if (fmt.dwMask) {
667  ME_Cursor from, to;
668  LONG start, end;
669 
670  ITextRange_GetStart(range, &start);
671  ITextRange_GetEnd(range, &end);
672 
675  ME_SetCharFormat(reole->editor, &from, &to, &fmt);
676  }
677 }
678 
680 {
681  const IRichEditOleImpl *reole;
683  LONG start, end, i;
684  HRESULT hr;
685 
686  /* when font is not attached to any range use cached values */
687  if (!font->range || font->get_cache_enabled) {
688  *value = font->props[propid];
689  return S_OK;
690  }
691 
692  if (!(reole = get_range_reole(font->range)))
693  return CO_E_RELEASED;
694 
696 
697  ITextRange_GetStart(font->range, &start);
698  ITextRange_GetEnd(font->range, &end);
699 
700  /* iterate trough a range to see if property value is consistent */
701  hr = get_textfont_prop_for_pos(reole, start, propid, &v);
702  if (FAILED(hr))
703  return hr;
704 
705  for (i = start + 1; i < end; i++) {
706  textfont_prop_val cur;
707 
708  hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
709  if (FAILED(hr))
710  return hr;
711 
712  if (!is_equal_textfont_prop_value(propid, &v, &cur))
713  return S_OK;
714  }
715 
716  *value = v;
717  return S_OK;
718 }
719 
721 {
723  HRESULT hr;
724 
725  if (!value)
726  return E_INVALIDARG;
727 
728  hr = get_textfont_prop(font, propid, &v);
729  *value = v.f;
730  return hr;
731 }
732 
734 {
736  HRESULT hr;
737 
738  if (!value)
739  return E_INVALIDARG;
740 
741  hr = get_textfont_prop(font, propid, &v);
742  *value = v.l;
743  return hr;
744 }
745 
746 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
748 {
749  const IRichEditOleImpl *reole;
750  ME_Cursor from, to;
752  LONG start, end;
753 
754  /* when font is not attached to any range use cache */
755  if (!font->range || font->set_cache_enabled) {
756  if (propid == FONT_NAME) {
757  SysFreeString(font->props[propid].str);
758  font->props[propid].str = SysAllocString(value->str);
759  }
760  else
761  font->props[propid] = *value;
762  return S_OK;
763  }
764 
765  if (!(reole = get_range_reole(font->range)))
766  return CO_E_RELEASED;
767 
768  memset(&fmt, 0, sizeof(fmt));
769  fmt.cbSize = sizeof(fmt);
770  fmt.dwMask = textfont_prop_masks[propid][0];
771 
772  switch (propid)
773  {
774  case FONT_ALLCAPS:
775  case FONT_BOLD:
776  case FONT_EMBOSS:
777  case FONT_HIDDEN:
778  case FONT_ENGRAVE:
779  case FONT_ITALIC:
780  case FONT_OUTLINE:
781  case FONT_PROTECTED:
782  case FONT_SHADOW:
783  case FONT_SMALLCAPS:
784  case FONT_STRIKETHROUGH:
785  case FONT_SUBSCRIPT:
786  case FONT_SUPERSCRIPT:
787  case FONT_UNDERLINE:
788  fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
789  break;
790  case FONT_ANIMATION:
791  fmt.bAnimation = value->l;
792  break;
793  case FONT_BACKCOLOR:
794  case FONT_FORECOLOR:
795  if (value->l == tomAutoColor)
796  fmt.dwEffects = textfont_prop_masks[propid][1];
797  else if (propid == FONT_BACKCOLOR)
798  fmt.crBackColor = value->l;
799  else
800  fmt.crTextColor = value->l;
801  break;
802  case FONT_KERNING:
803  fmt.wKerning = value->f;
804  break;
805  case FONT_LANGID:
806  fmt.lcid = value->l;
807  break;
808  case FONT_POSITION:
809  fmt.yOffset = value->f;
810  break;
811  case FONT_SIZE:
812  fmt.yHeight = value->f;
813  break;
814  case FONT_SPACING:
815  fmt.sSpacing = value->f;
816  break;
817  case FONT_WEIGHT:
818  fmt.wWeight = value->l;
819  break;
820  case FONT_NAME:
821  lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
822  break;
823  default:
824  FIXME("unhandled font property %d\n", propid);
825  return E_FAIL;
826  }
827 
828  ITextRange_GetStart(font->range, &start);
829  ITextRange_GetEnd(font->range, &end);
830 
833  ME_SetCharFormat(reole->editor, &from, &to, &fmt);
834 
835  return S_OK;
836 }
837 
839 {
841  v.l = value;
842  return set_textfont_prop(font, propid, &v);
843 }
844 
846 {
848  v.f = value;
849  return set_textfont_prop(font, propid, &v);
850 }
851 
853 {
855 
856  switch (value)
857  {
858  case tomUndefined:
859  return S_OK;
860  case tomToggle: {
861  LONG oldvalue;
862  get_textfont_propl(font, propid, &oldvalue);
863  if (oldvalue == tomFalse)
864  value = tomTrue;
865  else if (oldvalue == tomTrue)
866  value = tomFalse;
867  else
868  return E_INVALIDARG;
869  /* fallthrough */
870  }
871  case tomTrue:
872  case tomFalse:
873  v.l = value;
874  return set_textfont_prop(font, propid, &v);
875  default:
876  return E_INVALIDARG;
877  }
878 }
879 
881 {
882  const IRichEditOleImpl *reole;
884  HRESULT hr;
885  LONG start;
886 
887  if (!(reole = get_range_reole(range)))
888  return CO_E_RELEASED;
889 
890  ITextRange_GetStart(range, &start);
892  *ret = v.str;
893  return hr;
894 }
895 
897 {
898  enum textfont_prop_id propid;
899  for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
900  if (propid == FONT_NAME)
901  textfont_getname_from_range(font->range, &font->props[propid].str);
902  else
903  get_textfont_prop(font, propid, &font->props[propid]);
904  }
905 }
906 
908 {
909  LONG expand_start, expand_end;
910 
911  switch (unit)
912  {
913  case tomStory:
914  expand_start = 0;
915  ITextRange_GetStoryLength(range, &expand_end);
916  break;
917  default:
918  FIXME("unit %d is not supported\n", unit);
919  return E_NOTIMPL;
920  }
921 
922  if (delta) {
923  LONG start, end;
924 
925  ITextRange_GetStart(range, &start);
926  ITextRange_GetEnd(range, &end);
927  *delta = expand_end - expand_start - (end - start);
928  }
929 
930  ITextRange_SetStart(range, expand_start);
931  ITextRange_SetEnd(range, expand_end);
932 
933  return S_OK;
934 }
935 
937 {
939 
940  TRACE("%p %s\n", This, debugstr_guid(riid));
941 
942  *ppvObj = NULL;
944  *ppvObj = &This->IUnknown_inner;
945  else if (IsEqualGUID(riid, &IID_IRichEditOle))
946  *ppvObj = &This->IRichEditOle_iface;
947  else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old))
948  *ppvObj = &This->ITextDocument2Old_iface;
949  if (*ppvObj)
950  {
951  IUnknown_AddRef((IUnknown *)*ppvObj);
952  return S_OK;
953  }
954 
955  if (IsEqualGUID(riid, &IID_ITextServices))
956  {
957  static int once;
958  if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This);
959  return E_NOINTERFACE;
960  }
961 
962  FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
963 
964  return E_NOINTERFACE;
965 }
966 
968 {
971 
972  TRACE("%p ref = %u\n", This, ref);
973 
974  return ref;
975 }
976 
978 {
981 
982  TRACE ("%p ref=%u\n", This, ref);
983 
984  if (!ref)
985  {
986  IOleClientSiteImpl *clientsite;
987  ITextRangeImpl *txtRge;
988 
989  This->editor->reOle = NULL;
990  if (This->txtSel) {
991  This->txtSel->reOle = NULL;
992  ITextSelection_Release(&This->txtSel->ITextSelection_iface);
993  }
994 
995  LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
996  txtRge->child.reole = NULL;
997 
998  LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
999  clientsite->child.reole = NULL;
1000 
1001  heap_free(This);
1002  }
1003  return ref;
1004 }
1005 
1006 static const IUnknownVtbl reo_unk_vtbl =
1007 {
1011 };
1012 
1013 static HRESULT WINAPI
1015 {
1017  return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1018 }
1019 
1020 static ULONG WINAPI
1022 {
1024  return IUnknown_AddRef(This->outer_unk);
1025 }
1026 
1027 static ULONG WINAPI
1029 {
1031  return IUnknown_Release(This->outer_unk);
1032 }
1033 
1034 static HRESULT WINAPI
1036 {
1038  FIXME("stub %p\n",This);
1039  return E_NOTIMPL;
1040 }
1041 
1042 static HRESULT WINAPI
1044 {
1046  FIXME("stub %p\n",This);
1047  return E_NOTIMPL;
1048 }
1049 
1050 static HRESULT WINAPI
1052  REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1053 {
1055  FIXME("stub %p\n",This);
1056  return E_NOTIMPL;
1057 }
1058 
1060 {
1061  return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1062 }
1063 
1064 static HRESULT WINAPI
1066 {
1068  TRACE("%p %s\n", me, debugstr_guid(riid) );
1069 
1070  *ppvObj = NULL;
1071  if (IsEqualGUID(riid, &IID_IUnknown) ||
1073  *ppvObj = me;
1074  else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1076  *ppvObj = &This->IOleInPlaceSite_iface;
1077  if (*ppvObj)
1078  {
1079  IOleClientSite_AddRef(me);
1080  return S_OK;
1081  }
1082  FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1083 
1084  return E_NOINTERFACE;
1085 }
1086 
1088 {
1091  TRACE("(%p)->(%u)\n", This, ref);
1092  return ref;
1093 }
1094 
1096 {
1099 
1100  TRACE("(%p)->(%u)\n", This, ref);
1101 
1102  if (ref == 0) {
1103  if (This->child.reole) {
1104  list_remove(&This->child.entry);
1105  This->child.reole = NULL;
1106  }
1107  heap_free(This);
1108  }
1109  return ref;
1110 }
1111 
1113 {
1115  if (!This->child.reole)
1116  return CO_E_RELEASED;
1117 
1118  FIXME("stub %p\n", iface);
1119  return E_NOTIMPL;
1120 }
1121 
1123  DWORD dwWhichMoniker, IMoniker **ppmk)
1124 {
1126  if (!This->child.reole)
1127  return CO_E_RELEASED;
1128 
1129  FIXME("stub %p\n", iface);
1130  return E_NOTIMPL;
1131 }
1132 
1134  IOleContainer **ppContainer)
1135 {
1137  if (!This->child.reole)
1138  return CO_E_RELEASED;
1139 
1140  FIXME("stub %p\n", iface);
1141  return E_NOTIMPL;
1142 }
1143 
1145 {
1147  if (!This->child.reole)
1148  return CO_E_RELEASED;
1149 
1150  FIXME("stub %p\n", iface);
1151  return E_NOTIMPL;
1152 }
1153 
1155 {
1157  if (!This->child.reole)
1158  return CO_E_RELEASED;
1159 
1160  FIXME("stub %p\n", iface);
1161  return E_NOTIMPL;
1162 }
1163 
1165 {
1167  if (!This->child.reole)
1168  return CO_E_RELEASED;
1169 
1170  FIXME("stub %p\n", iface);
1171  return E_NOTIMPL;
1172 }
1173 
1174 static const IOleClientSiteVtbl ocst = {
1184 };
1185 
1186 /* IOleInPlaceSite interface */
1188 {
1190  return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1191 }
1192 
1194 {
1196  return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1197 }
1198 
1200 {
1202  return IOleClientSite_Release(&This->IOleClientSite_iface);
1203 }
1204 
1206 {
1208 
1209  TRACE("(%p)->(%p)\n", This, phwnd);
1210 
1211  if (!This->child.reole)
1212  return CO_E_RELEASED;
1213 
1214  if (!phwnd)
1215  return E_INVALIDARG;
1216 
1217  *phwnd = This->child.reole->editor->hWnd;
1218  return S_OK;
1219 }
1220 
1222 {
1224  FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1225  return E_NOTIMPL;
1226 }
1227 
1229 {
1231  FIXME("not implemented: (%p)\n", This);
1232  return E_NOTIMPL;
1233 }
1234 
1236 {
1238  FIXME("not implemented: (%p)\n", This);
1239  return E_NOTIMPL;
1240 }
1241 
1243 {
1245  FIXME("not implemented: (%p)\n", This);
1246  return E_NOTIMPL;
1247 }
1248 
1250  IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1251  LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1252 {
1254  FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1255  return E_NOTIMPL;
1256 }
1257 
1259 {
1261  FIXME("not implemented: (%p)\n", This);
1262  return E_NOTIMPL;
1263 }
1264 
1266 {
1268  FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1269  return E_NOTIMPL;
1270 }
1271 
1273 {
1275  FIXME("not implemented: (%p)\n", This);
1276  return E_NOTIMPL;
1277 }
1278 
1280 {
1282  FIXME("not implemented: (%p)\n", This);
1283  return E_NOTIMPL;
1284 }
1285 
1287 {
1289  FIXME("not implemented: (%p)\n", This);
1290  return E_NOTIMPL;
1291 }
1292 
1294 {
1296  FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1297  return E_NOTIMPL;
1298 }
1299 
1300 static const IOleInPlaceSiteVtbl olestvt =
1301 {
1317 };
1318 
1320 {
1321  IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1322 
1323  if (!clientSite)
1324  return E_OUTOFMEMORY;
1325 
1326  clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1327  clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1328  clientSite->ref = 1;
1329  clientSite->child.reole = reOle;
1330  list_add_head(&reOle->clientsites, &clientSite->child.entry);
1331 
1332  *ret = &clientSite->IOleClientSite_iface;
1333  return S_OK;
1334 }
1335 
1336 static HRESULT WINAPI
1338 {
1340 
1341  TRACE("(%p)->(%p)\n", This, clientsite);
1342 
1343  if (!clientsite)
1344  return E_INVALIDARG;
1345 
1346  return CreateOleClientSite(This, clientsite);
1347 }
1348 
1349 static HRESULT WINAPI
1351  DWORD reco, LPDATAOBJECT *lplpdataobj)
1352 {
1354  ME_Cursor start;
1355  int nChars;
1356 
1357  TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1358  if(!lplpdataobj)
1359  return E_INVALIDARG;
1360  if(!lpchrg) {
1361  int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1362  start = This->editor->pCursors[nStartCur];
1363  nChars = nTo - nFrom;
1364  } else {
1365  ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1366  nChars = lpchrg->cpMax - lpchrg->cpMin;
1367  }
1368  return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1369 }
1370 
1372 {
1374  FIXME("stub %p\n",This);
1375  return E_NOTIMPL;
1376 }
1377 
1378 static HRESULT WINAPI
1380  REOBJECT *lpreobject, DWORD dwFlags)
1381 {
1383  struct re_object *reobj = NULL;
1384  LONG count = 0;
1385 
1386  TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1387 
1388  if (!lpreobject || !lpreobject->cbStruct)
1389  return E_INVALIDARG;
1390 
1391  if (iob == REO_IOB_USE_CP)
1392  {
1393  ME_Cursor cursor;
1394 
1395  TRACE("character offset: %d\n", lpreobject->cp);
1396  ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
1397  if (!cursor.pRun->member.run.reobj)
1398  return E_INVALIDARG;
1399  else
1400  reobj = cursor.pRun->member.run.reobj;
1401  }
1402  else if (iob == REO_IOB_SELECTION)
1403  {
1404  ME_Cursor *from, *to;
1405 
1406  ME_GetSelection(This->editor, &from, &to);
1407  if (!from->pRun->member.run.reobj)
1408  return E_INVALIDARG;
1409  else
1410  reobj = from->pRun->member.run.reobj;
1411  }
1412  else
1413  {
1414  if (iob > IRichEditOle_GetObjectCount(me))
1415  return E_INVALIDARG;
1416  LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1417  {
1418  if (count == iob)
1419  break;
1420  count++;
1421  }
1422  }
1423  ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1424  return S_OK;
1425 }
1426 
1427 static LONG WINAPI
1429 {
1431  TRACE("(%p)\n",This);
1432  return list_count(&This->editor->reobj_list);
1433 }
1434 
1435 static HRESULT WINAPI
1437 {
1439  FIXME("stub %p\n",This);
1440  return E_NOTIMPL;
1441 }
1442 
1443 static HRESULT WINAPI
1445  CLIPFORMAT cf, HGLOBAL hMetaPict)
1446 {
1448  FIXME("stub %p\n",This);
1449  return E_NOTIMPL;
1450 }
1451 
1452 static HRESULT WINAPI
1454 {
1456  FIXME("stub %p\n",This);
1457  return E_NOTIMPL;
1458 }
1459 
1460 static HRESULT WINAPI
1462 {
1464 
1465  TRACE("(%p,%p)\n", This, reo);
1466 
1467  if (!reo)
1468  return E_INVALIDARG;
1469 
1470  if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1471 
1472  ME_InsertOLEFromCursor(This->editor, reo, 0);
1473  ME_CommitUndo(This->editor);
1474  ME_UpdateRepaint(This->editor, FALSE);
1475  return S_OK;
1476 }
1477 
1479  LPSTORAGE lpstg)
1480 {
1482  FIXME("stub %p\n",This);
1483  return E_NOTIMPL;
1484 }
1485 
1486 static HRESULT WINAPI
1488 {
1490  FIXME("stub %p\n",This);
1491  return E_NOTIMPL;
1492 }
1493 
1495  LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1496 {
1498  FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1499  return E_NOTIMPL;
1500 }
1501 
1502 static HRESULT WINAPI
1504 {
1506  FIXME("stub %p\n",This);
1507  return E_NOTIMPL;
1508 }
1509 
1510 static const IRichEditOleVtbl revt = {
1530 };
1531 
1532 /* ITextRange interface */
1534 {
1536 
1537  *ppvObj = NULL;
1540  || IsEqualGUID(riid, &IID_ITextRange))
1541  {
1542  *ppvObj = me;
1543  ITextRange_AddRef(me);
1544  return S_OK;
1545  }
1546  else if (IsEqualGUID(riid, &IID_Igetrichole))
1547  {
1548  *ppvObj = This->child.reole;
1549  return S_OK;
1550  }
1551 
1552  return E_NOINTERFACE;
1553 }
1554 
1556 {
1558  return InterlockedIncrement(&This->ref);
1559 }
1560 
1562 {
1565 
1566  TRACE ("%p ref=%u\n", This, ref);
1567  if (ref == 0)
1568  {
1569  if (This->child.reole)
1570  {
1571  list_remove(&This->child.entry);
1572  This->child.reole = NULL;
1573  }
1574  heap_free(This);
1575  }
1576  return ref;
1577 }
1578 
1580 {
1582  TRACE("(%p)->(%p)\n", This, pctinfo);
1583  *pctinfo = 1;
1584  return S_OK;
1585 }
1586 
1588  ITypeInfo **ppTInfo)
1589 {
1591  HRESULT hr;
1592 
1593  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1594 
1595  hr = get_typeinfo(ITextRange_tid, ppTInfo);
1596  if (SUCCEEDED(hr))
1597  ITypeInfo_AddRef(*ppTInfo);
1598  return hr;
1599 }
1600 
1602  UINT cNames, LCID lcid, DISPID *rgDispId)
1603 {
1605  ITypeInfo *ti;
1606  HRESULT hr;
1607 
1608  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1609  rgDispId);
1610 
1611  hr = get_typeinfo(ITextRange_tid, &ti);
1612  if (SUCCEEDED(hr))
1613  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1614  return hr;
1615 }
1616 
1618  LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1619  VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1620  UINT *puArgErr)
1621 {
1623  ITypeInfo *ti;
1624  HRESULT hr;
1625 
1626  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1627  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1628 
1629  hr = get_typeinfo(ITextRange_tid, &ti);
1630  if (SUCCEEDED(hr))
1631  hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1632  return hr;
1633 }
1634 
1636 {
1638  ME_TextEditor *editor;
1639  ME_Cursor start, end;
1640  int length;
1641  BOOL bEOP;
1642 
1643  TRACE("(%p)->(%p)\n", This, str);
1644 
1645  if (!This->child.reole)
1646  return CO_E_RELEASED;
1647 
1648  if (!str)
1649  return E_INVALIDARG;
1650 
1651  /* return early for degenerate range */
1652  if (This->start == This->end) {
1653  *str = NULL;
1654  return S_OK;
1655  }
1656 
1657  editor = This->child.reole->editor;
1658  ME_CursorFromCharOfs(editor, This->start, &start);
1659  ME_CursorFromCharOfs(editor, This->end, &end);
1660 
1661  length = This->end - This->start;
1663  if (!*str)
1664  return E_OUTOFMEMORY;
1665 
1666  bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1667  ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1668  return S_OK;
1669 }
1670 
1672 {
1674  ME_TextEditor *editor;
1675  ME_Cursor cursor;
1676  ME_Style *style;
1677  int len;
1678 
1679  TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1680 
1681  if (!This->child.reole)
1682  return CO_E_RELEASED;
1683 
1684  editor = This->child.reole->editor;
1685 
1686  /* delete only where's something to delete */
1687  if (This->start != This->end) {
1688  ME_CursorFromCharOfs(editor, This->start, &cursor);
1689  ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1690  }
1691 
1692  if (!str || !*str) {
1693  /* will update this range as well */
1694  textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1695  return S_OK;
1696  }
1697 
1698  /* it's safer not to rely on stored BSTR length */
1699  len = lstrlenW(str);
1700  cursor = editor->pCursors[0];
1701  ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1702  style = ME_GetInsertStyle(editor, 0);
1703  ME_InsertTextFromCursor(editor, 0, str, len, style);
1705  editor->pCursors[0] = cursor;
1706 
1707  if (len < This->end - This->start)
1708  textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1709  else
1710  This->end = len - This->start;
1711 
1712  return S_OK;
1713 }
1714 
1716 {
1717  WCHAR wch[2];
1718 
1719  ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1720  *pch = wch[0];
1721 
1722  return S_OK;
1723 }
1724 
1726 {
1728  ME_TextEditor *editor;
1729  ME_Cursor cursor;
1730 
1731  TRACE("(%p)->(%p)\n", This, pch);
1732 
1733  if (!This->child.reole)
1734  return CO_E_RELEASED;
1735 
1736  if (!pch)
1737  return E_INVALIDARG;
1738 
1739  editor = This->child.reole->editor;
1740  ME_CursorFromCharOfs(editor, This->start, &cursor);
1741  return range_GetChar(editor, &cursor, pch);
1742 }
1743 
1745 {
1747 
1748  FIXME("(%p)->(%x): stub\n", This, ch);
1749 
1750  if (!This->child.reole)
1751  return CO_E_RELEASED;
1752 
1753  return E_NOTIMPL;
1754 }
1755 
1757 
1759 {
1761 
1762  TRACE("(%p)->(%p)\n", This, ppRange);
1763 
1764  if (!This->child.reole)
1765  return CO_E_RELEASED;
1766 
1767  if (!ppRange)
1768  return E_INVALIDARG;
1769 
1770  return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1771 }
1772 
1774 {
1776 
1777  FIXME("(%p)->(%p): stub\n", This, range);
1778 
1779  if (!This->child.reole)
1780  return CO_E_RELEASED;
1781 
1782  return E_NOTIMPL;
1783 }
1784 
1786 {
1788 
1789  FIXME("(%p)->(%p): stub\n", This, range);
1790 
1791  if (!This->child.reole)
1792  return CO_E_RELEASED;
1793 
1794  return E_NOTIMPL;
1795 }
1796 
1798 {
1800 
1801  TRACE("(%p)->(%p)\n", This, start);
1802 
1803  if (!This->child.reole)
1804  return CO_E_RELEASED;
1805 
1806  if (!start)
1807  return E_INVALIDARG;
1808 
1809  *start = This->start;
1810  return S_OK;
1811 }
1812 
1814 {
1815  int len;
1816 
1817  if (value < 0)
1818  value = 0;
1819 
1820  if (value == *start)
1821  return S_FALSE;
1822 
1823  if (value <= *end) {
1824  *start = value;
1825  return S_OK;
1826  }
1827 
1828  len = ME_GetTextLength(reole->editor);
1829  *start = *end = value > len ? len : value;
1830  return S_OK;
1831 }
1832 
1834 {
1836 
1837  TRACE("(%p)->(%d)\n", This, value);
1838 
1839  if (!This->child.reole)
1840  return CO_E_RELEASED;
1841 
1842  return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1843 }
1844 
1846 {
1848 
1849  TRACE("(%p)->(%p)\n", This, end);
1850 
1851  if (!This->child.reole)
1852  return CO_E_RELEASED;
1853 
1854  if (!end)
1855  return E_INVALIDARG;
1856 
1857  *end = This->end;
1858  return S_OK;
1859 }
1860 
1862 {
1863  int len;
1864 
1865  if (value == *end)
1866  return S_FALSE;
1867 
1868  if (value < *start) {
1869  *start = *end = max(0, value);
1870  return S_OK;
1871  }
1872 
1873  len = ME_GetTextLength(reole->editor);
1874  *end = value > len ? len + 1 : value;
1875  return S_OK;
1876 }
1877 
1879 {
1881 
1882  TRACE("(%p)->(%d)\n", This, value);
1883 
1884  if (!This->child.reole)
1885  return CO_E_RELEASED;
1886 
1887  return textrange_setend(This->child.reole, value, &This->start, &This->end);
1888 }
1889 
1891 {
1893 
1894  TRACE("(%p)->(%p)\n", This, font);
1895 
1896  if (!This->child.reole)
1897  return CO_E_RELEASED;
1898 
1899  if (!font)
1900  return E_INVALIDARG;
1901 
1902  return create_textfont(me, NULL, font);
1903 }
1904 
1906 {
1908 
1909  TRACE("(%p)->(%p)\n", This, font);
1910 
1911  if (!font)
1912  return E_INVALIDARG;
1913 
1914  if (!This->child.reole)
1915  return CO_E_RELEASED;
1916 
1917  textrange_set_font(me, font);
1918  return S_OK;
1919 }
1920 
1922 {
1924 
1925  TRACE("(%p)->(%p)\n", This, para);
1926 
1927  if (!This->child.reole)
1928  return CO_E_RELEASED;
1929 
1930  if (!para)
1931  return E_INVALIDARG;
1932 
1933  return create_textpara(me, para);
1934 }
1935 
1937 {
1939 
1940  FIXME("(%p)->(%p): stub\n", This, para);
1941 
1942  if (!This->child.reole)
1943  return CO_E_RELEASED;
1944 
1945  return E_NOTIMPL;
1946 }
1947 
1949 {
1951 
1952  TRACE("(%p)->(%p)\n", This, length);
1953 
1954  if (!This->child.reole)
1955  return CO_E_RELEASED;
1956 
1957  return textrange_get_storylength(This->child.reole->editor, length);
1958 }
1959 
1961 {
1963 
1964  TRACE("(%p)->(%p)\n", This, value);
1965 
1966  if (!This->child.reole)
1967  return CO_E_RELEASED;
1968 
1969  if (!value)
1970  return E_INVALIDARG;
1971 
1973  return S_OK;
1974 }
1975 
1977 {
1978  if (*end == *start)
1979  return S_FALSE;
1980 
1981  if (bStart == tomEnd)
1982  *start = *end;
1983  else
1984  *end = *start;
1985  return S_OK;
1986 }
1987 
1989 {
1991 
1992  TRACE("(%p)->(%d)\n", This, bStart);
1993 
1994  if (!This->child.reole)
1995  return CO_E_RELEASED;
1996 
1997  return range_Collapse(bStart, &This->start, &This->end);
1998 }
1999 
2001 {
2003 
2004  TRACE("(%p)->(%d %p)\n", This, unit, delta);
2005 
2006  if (!This->child.reole)
2007  return CO_E_RELEASED;
2008 
2009  return textrange_expand(me, unit, delta);
2010 }
2011 
2013 {
2015 
2016  FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2017 
2018  if (!This->child.reole)
2019  return CO_E_RELEASED;
2020 
2021  return E_NOTIMPL;
2022 }
2023 
2025  LONG extend)
2026 {
2028 
2029  FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2030 
2031  if (!This->child.reole)
2032  return CO_E_RELEASED;
2033 
2034  return E_NOTIMPL;
2035 }
2036 
2037 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
2038 {
2039  int len = ME_GetTextLength(editor) + 1;
2040 
2041  *cp1 = max(*cp1, 0);
2042  *cp2 = max(*cp2, 0);
2043  *cp1 = min(*cp1, len);
2044  *cp2 = min(*cp2, len);
2045  if (*cp1 > *cp2)
2046  {
2047  int tmp = *cp1;
2048  *cp1 = *cp2;
2049  *cp2 = tmp;
2050  }
2051  if (*cp1 == len)
2052  *cp1 = *cp2 = len - 1;
2053 }
2054 
2056 {
2058 
2059  FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2060 
2061  if (!This->child.reole)
2062  return CO_E_RELEASED;
2063 
2064  cp2range(This->child.reole->editor, &anchor, &active);
2065  if (anchor == This->start && active == This->end)
2066  return S_FALSE;
2067 
2068  This->start = anchor;
2069  This->end = active;
2070  return S_OK;
2071 }
2072 
2074 {
2075  LONG from, to, v;
2076 
2077  if (!ret)
2078  ret = &v;
2079 
2080  if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2081  *ret = tomFalse;
2082  }
2083  else
2084  *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2085  return *ret == tomTrue ? S_OK : S_FALSE;
2086 }
2087 
2089 {
2091 
2092  TRACE("(%p)->(%p %p)\n", This, range, ret);
2093 
2094  if (ret)
2095  *ret = tomFalse;
2096 
2097  if (!This->child.reole)
2098  return CO_E_RELEASED;
2099 
2100  if (!range)
2101  return S_FALSE;
2102 
2103  return textrange_inrange(This->start, This->end, range, ret);
2104 }
2105 
2107 {
2109 
2110  FIXME("(%p)->(%p): stub\n", This, ret);
2111 
2112  if (!This->child.reole)
2113  return CO_E_RELEASED;
2114 
2115  return E_NOTIMPL;
2116 }
2117 
2119 {
2120  LONG from, to, v;
2121 
2122  if (!ret)
2123  ret = &v;
2124 
2125  if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2126  *ret = tomFalse;
2127  }
2128  else
2129  *ret = (start == from && end == to) ? tomTrue : tomFalse;
2130  return *ret == tomTrue ? S_OK : S_FALSE;
2131 }
2132 
2134 {
2136 
2137  TRACE("(%p)->(%p %p)\n", This, range, ret);
2138 
2139  if (ret)
2140  *ret = tomFalse;
2141 
2142  if (!This->child.reole)
2143  return CO_E_RELEASED;
2144 
2145  if (!range)
2146  return S_FALSE;
2147 
2148  return textrange_isequal(This->start, This->end, range, ret);
2149 }
2150 
2152 {
2154 
2155  TRACE("(%p)\n", This);
2156 
2157  if (!This->child.reole)
2158  return CO_E_RELEASED;
2159 
2160  set_selection(This->child.reole->editor, This->start, This->end);
2161  return S_OK;
2162 }
2163 
2165  LONG *delta)
2166 {
2168 
2169  FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2170 
2171  if (!This->child.reole)
2172  return CO_E_RELEASED;
2173 
2174  return E_NOTIMPL;
2175 }
2176 
2178  LONG *delta)
2179 {
2181 
2182  FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2183 
2184  if (!This->child.reole)
2185  return CO_E_RELEASED;
2186 
2187  return E_NOTIMPL;
2188 }
2189 
2191 {
2193 
2194  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2195 
2196  if (!This->child.reole)
2197  return CO_E_RELEASED;
2198 
2199  return E_NOTIMPL;
2200 }
2201 
2203  LONG *delta)
2204 {
2206 
2207  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2208 
2209  if (!This->child.reole)
2210  return CO_E_RELEASED;
2211 
2212  return E_NOTIMPL;
2213 }
2214 
2216 {
2217  LONG old_start, old_end, new_start, new_end;
2218  HRESULT hr = S_OK;
2219 
2220  if (!count)
2221  {
2222  if (delta)
2223  *delta = 0;
2224  return S_FALSE;
2225  }
2226 
2227  ITextRange_GetStart(range, &old_start);
2228  ITextRange_GetEnd(range, &old_end);
2229  switch (unit)
2230  {
2231  case tomStory:
2232  if (count < 0)
2233  new_start = new_end = 0;
2234  else
2235  {
2236  new_start = old_start;
2237  ITextRange_GetStoryLength(range, &new_end);
2238  }
2239  if (delta)
2240  {
2241  if (new_end < old_end)
2242  *delta = -1;
2243  else if (new_end == old_end)
2244  *delta = 0;
2245  else
2246  *delta = 1;
2247  }
2248  break;
2249  default:
2250  FIXME("unit %d is not supported\n", unit);
2251  return E_NOTIMPL;
2252  }
2253  if (new_end == old_end)
2254  hr = S_FALSE;
2255  ITextRange_SetStart(range, new_start);
2256  ITextRange_SetEnd(range, new_end);
2257 
2258  return hr;
2259 }
2260 
2262  LONG *delta)
2263 {
2265 
2266  TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2267 
2268  if (!This->child.reole)
2269  return CO_E_RELEASED;
2270 
2271  return textrange_moveend(me, unit, count, delta);
2272 }
2273 
2275  LONG *delta)
2276 {
2278 
2279  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2280 
2281  if (!This->child.reole)
2282  return CO_E_RELEASED;
2283 
2284  return E_NOTIMPL;
2285 }
2286 
2288  LONG *delta)
2289 {
2291 
2292  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2293 
2294  if (!This->child.reole)
2295  return CO_E_RELEASED;
2296 
2297  return E_NOTIMPL;
2298 }
2299 
2301  LONG *delta)
2302 {
2304 
2305  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2306 
2307  if (!This->child.reole)
2308  return CO_E_RELEASED;
2309 
2310  return E_NOTIMPL;
2311 }
2312 
2314  LONG *delta)
2315 {
2317 
2318  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2319 
2320  if (!This->child.reole)
2321  return CO_E_RELEASED;
2322 
2323  return E_NOTIMPL;
2324 }
2325 
2327  LONG *delta)
2328 {
2330 
2331  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2332 
2333  if (!This->child.reole)
2334  return CO_E_RELEASED;
2335 
2336  return E_NOTIMPL;
2337 }
2338 
2340  LONG *delta)
2341 {
2343 
2344  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2345 
2346  if (!This->child.reole)
2347  return CO_E_RELEASED;
2348 
2349  return E_NOTIMPL;
2350 }
2351 
2353  LONG *length)
2354 {
2356 
2357  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2358 
2359  if (!This->child.reole)
2360  return CO_E_RELEASED;
2361 
2362  return E_NOTIMPL;
2363 }
2364 
2366  LONG flags, LONG *length)
2367 {
2369 
2370  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2371 
2372  if (!This->child.reole)
2373  return CO_E_RELEASED;
2374 
2375  return E_NOTIMPL;
2376 }
2377 
2379  LONG flags, LONG *length)
2380 {
2382 
2383  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2384 
2385  if (!This->child.reole)
2386  return CO_E_RELEASED;
2387 
2388  return E_NOTIMPL;
2389 }
2390 
2392 {
2394 
2395  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2396 
2397  if (!This->child.reole)
2398  return CO_E_RELEASED;
2399 
2400  return E_NOTIMPL;
2401 }
2402 
2404 {
2406 
2407  FIXME("(%p)->(%p): stub\n", This, v);
2408 
2409  if (!This->child.reole)
2410  return CO_E_RELEASED;
2411 
2412  return E_NOTIMPL;
2413 }
2414 
2416 {
2418 
2419  FIXME("(%p)->(%p): stub\n", This, v);
2420 
2421  if (!This->child.reole)
2422  return CO_E_RELEASED;
2423 
2424  return E_NOTIMPL;
2425 }
2426 
2428 {
2430 
2431  FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2432 
2433  if (!This->child.reole)
2434  return CO_E_RELEASED;
2435 
2436  return E_NOTIMPL;
2437 }
2438 
2440 {
2442 
2443  FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2444 
2445  if (!This->child.reole)
2446  return CO_E_RELEASED;
2447 
2448  return E_NOTIMPL;
2449 }
2450 
2452 {
2454 
2455  FIXME("(%p)->(%p): stub\n", This, ret);
2456 
2457  if (!This->child.reole)
2458  return CO_E_RELEASED;
2459 
2460  return E_NOTIMPL;
2461 }
2462 
2464 {
2466 
2467  FIXME("(%p)->(%d): stub\n", This, type);
2468 
2469  if (!This->child.reole)
2470  return CO_E_RELEASED;
2471 
2472  return E_NOTIMPL;
2473 }
2474 
2476 {
2478 
2479  FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2480 
2481  if (!This->child.reole)
2482  return CO_E_RELEASED;
2483 
2484  return E_NOTIMPL;
2485 }
2486 
2488  LONG extend)
2489 {
2491 
2492  FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2493 
2494  if (!This->child.reole)
2495  return CO_E_RELEASED;
2496 
2497  return E_NOTIMPL;
2498 }
2499 
2501 {
2503  ME_TextEditor *editor;
2504  ME_Cursor cursor;
2505  int x, y, height;
2506 
2507  TRACE("(%p)->(%d)\n", This, value);
2508 
2509  if (!This->child.reole)
2510  return CO_E_RELEASED;
2511 
2512  editor = This->child.reole->editor;
2513 
2514  switch (value)
2515  {
2516  case tomStart:
2517  ME_CursorFromCharOfs(editor, This->start, &cursor);
2518  ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2519  break;
2520  case tomEnd:
2521  ME_CursorFromCharOfs(editor, This->end, &cursor);
2522  ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2523  break;
2524  default:
2525  FIXME("bStart value %d not handled\n", value);
2526  return E_NOTIMPL;
2527  }
2528  ME_ScrollAbs(editor, x, y);
2529  return S_OK;
2530 }
2531 
2533 {
2535 
2536  FIXME("(%p)->(%p): stub\n", This, ppv);
2537 
2538  if (!This->child.reole)
2539  return CO_E_RELEASED;
2540 
2541  return E_NOTIMPL;
2542 }
2543 
2544 static const ITextRangeVtbl trvt = {
2603 };
2604 
2605 /* ITextFont */
2607 {
2609 
2610  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2611 
2612  if (IsEqualIID(riid, &IID_ITextFont) ||
2615  {
2616  *ppv = iface;
2617  ITextFont_AddRef(iface);
2618  return S_OK;
2619  }
2620 
2621  *ppv = NULL;
2622  return E_NOINTERFACE;
2623 }
2624 
2626 {
2629  TRACE("(%p)->(%u)\n", This, ref);
2630  return ref;
2631 }
2632 
2634 {
2637 
2638  TRACE("(%p)->(%u)\n", This, ref);
2639 
2640  if (!ref)
2641  {
2642  if (This->range)
2643  ITextRange_Release(This->range);
2644  SysFreeString(This->props[FONT_NAME].str);
2645  heap_free(This);
2646  }
2647 
2648  return ref;
2649 }
2650 
2652 {
2654  TRACE("(%p)->(%p)\n", This, pctinfo);
2655  *pctinfo = 1;
2656  return S_OK;
2657 }
2658 
2660  ITypeInfo **ppTInfo)
2661 {
2663  HRESULT hr;
2664 
2665  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2666 
2667  hr = get_typeinfo(ITextFont_tid, ppTInfo);
2668  if (SUCCEEDED(hr))
2669  ITypeInfo_AddRef(*ppTInfo);
2670  return hr;
2671 }
2672 
2674  LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2675 {
2677  ITypeInfo *ti;
2678  HRESULT hr;
2679 
2680  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2681  rgszNames, cNames, lcid, rgDispId);
2682 
2683  hr = get_typeinfo(ITextFont_tid, &ti);
2684  if (SUCCEEDED(hr))
2685  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2686  return hr;
2687 }
2688 
2690  ITextFont *iface,
2691  DISPID dispIdMember,
2692  REFIID riid,
2693  LCID lcid,
2694  WORD wFlags,
2695  DISPPARAMS *pDispParams,
2696  VARIANT *pVarResult,
2697  EXCEPINFO *pExcepInfo,
2698  UINT *puArgErr)
2699 {
2701  ITypeInfo *ti;
2702  HRESULT hr;
2703 
2704  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2705  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2706 
2707  hr = get_typeinfo(ITextFont_tid, &ti);
2708  if (SUCCEEDED(hr))
2709  hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2710  return hr;
2711 }
2712 
2714 {
2716 
2717  TRACE("(%p)->(%p)\n", This, ret);
2718 
2719  if (!ret)
2720  return E_INVALIDARG;
2721 
2722  *ret = NULL;
2723  if (This->range && !get_range_reole(This->range))
2724  return CO_E_RELEASED;
2725 
2726  return create_textfont(NULL, This, ret);
2727 }
2728 
2730 {
2732  FIXME("(%p)->(%p): stub\n", This, pFont);
2733  return E_NOTIMPL;
2734 }
2735 
2737 {
2739  FIXME("(%p)->(%p): stub\n", This, ret);
2740  return E_NOTIMPL;
2741 }
2742 
2744 {
2746  FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2747  return E_NOTIMPL;
2748 }
2749 
2751 {
2752  enum textfont_prop_id id;
2753 
2754  for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2755  switch (id)
2756  {
2757  case FONT_ALLCAPS:
2758  case FONT_ANIMATION:
2759  case FONT_BOLD:
2760  case FONT_EMBOSS:
2761  case FONT_HIDDEN:
2762  case FONT_ENGRAVE:
2763  case FONT_ITALIC:
2764  case FONT_OUTLINE:
2765  case FONT_PROTECTED:
2766  case FONT_SHADOW:
2767  case FONT_SMALLCAPS:
2768  case FONT_STRIKETHROUGH:
2769  case FONT_SUBSCRIPT:
2770  case FONT_SUPERSCRIPT:
2771  case FONT_UNDERLINE:
2772  font->props[id].l = tomFalse;
2773  break;
2774  case FONT_BACKCOLOR:
2775  case FONT_FORECOLOR:
2776  font->props[id].l = tomAutoColor;
2777  break;
2778  case FONT_KERNING:
2779  case FONT_POSITION:
2780  case FONT_SIZE:
2781  case FONT_SPACING:
2782  font->props[id].f = 0.0;
2783  break;
2784  case FONT_LANGID:
2785  font->props[id].l = GetSystemDefaultLCID();
2786  break;
2787  case FONT_NAME: {
2788  static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2789  SysFreeString(font->props[id].str);
2790  font->props[id].str = SysAllocString(sysW);
2791  break;
2792  }
2793  case FONT_WEIGHT:
2794  font->props[id].l = FW_NORMAL;
2795  break;
2796  default:
2797  FIXME("font property %d not handled\n", id);
2798  }
2799  }
2800 }
2801 
2803 {
2804  enum textfont_prop_id id;
2805 
2806  for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2807  switch (id)
2808  {
2809  case FONT_ALLCAPS:
2810  case FONT_ANIMATION:
2811  case FONT_BOLD:
2812  case FONT_EMBOSS:
2813  case FONT_HIDDEN:
2814  case FONT_ENGRAVE:
2815  case FONT_ITALIC:
2816  case FONT_OUTLINE:
2817  case FONT_PROTECTED:
2818  case FONT_SHADOW:
2819  case FONT_SMALLCAPS:
2820  case FONT_STRIKETHROUGH:
2821  case FONT_SUBSCRIPT:
2822  case FONT_SUPERSCRIPT:
2823  case FONT_UNDERLINE:
2824  case FONT_BACKCOLOR:
2825  case FONT_FORECOLOR:
2826  case FONT_LANGID:
2827  case FONT_WEIGHT:
2828  font->props[id].l = tomUndefined;
2829  break;
2830  case FONT_KERNING:
2831  case FONT_POSITION:
2832  case FONT_SIZE:
2833  case FONT_SPACING:
2834  font->props[id].f = tomUndefined;
2835  break;
2836  case FONT_NAME:
2837  break;
2838  default:
2839  FIXME("font property %d not handled\n", id);
2840  }
2841  }
2842 }
2843 
2845 {
2846  enum textfont_prop_id propid;
2847  for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2848  set_textfont_prop(font, propid, &font->props[propid]);
2849 }
2850 
2852 {
2854 
2855  TRACE("(%p)->(%d)\n", This, value);
2856 
2857  /* If font is attached to a range, released or not, we can't
2858  reset to undefined */
2859  if (This->range) {
2860  if (!get_range_reole(This->range))
2861  return CO_E_RELEASED;
2862 
2863  switch (value)
2864  {
2865  case tomUndefined:
2866  return E_INVALIDARG;
2867  case tomCacheParms:
2869  This->get_cache_enabled = TRUE;
2870  break;
2871  case tomTrackParms:
2872  This->get_cache_enabled = FALSE;
2873  break;
2874  case tomApplyLater:
2875  This->set_cache_enabled = TRUE;
2876  break;
2877  case tomApplyNow:
2878  This->set_cache_enabled = FALSE;
2880  break;
2881  case tomUsePoints:
2882  case tomUseTwips:
2883  return E_INVALIDARG;
2884  default:
2885  FIXME("reset mode %d not supported\n", value);
2886  }
2887 
2888  return S_OK;
2889  }
2890  else {
2891  switch (value)
2892  {
2893  /* reset to global defaults */
2894  case tomDefault:
2896  return S_OK;
2897  /* all properties are set to tomUndefined, font name is retained */
2898  case tomUndefined:
2900  return S_OK;
2901  case tomApplyNow:
2902  case tomApplyLater:
2903  case tomTrackParms:
2904  case tomCacheParms:
2905  return S_OK;
2906  case tomUsePoints:
2907  case tomUseTwips:
2908  return E_INVALIDARG;
2909  }
2910  }
2911 
2912  FIXME("reset mode %d not supported\n", value);
2913  return E_NOTIMPL;
2914 }
2915 
2917 {
2919  FIXME("(%p)->(%p): stub\n", This, value);
2920  return E_NOTIMPL;
2921 }
2922 
2924 {
2926  FIXME("(%p)->(%d): stub\n", This, value);
2927  return E_NOTIMPL;
2928 }
2929 
2931 {
2933  TRACE("(%p)->(%p)\n", This, value);
2935 }
2936 
2938 {
2940  TRACE("(%p)->(%d)\n", This, value);
2942 }
2943 
2945 {
2947  TRACE("(%p)->(%p)\n", This, value);
2949 }
2950 
2952 {
2954 
2955  TRACE("(%p)->(%d)\n", This, value);
2956 
2958  return E_INVALIDARG;
2959 
2961 }
2962 
2964 {
2966  TRACE("(%p)->(%p)\n", This, value);
2968 }
2969 
2971 {
2973  TRACE("(%p)->(%d)\n", This, value);
2975 }
2976 
2978 {
2980  TRACE("(%p)->(%p)\n", This, value);
2982 }
2983 
2985 {
2987  TRACE("(%p)->(%d)\n", This, value);
2989 }
2990 
2992 {
2994  TRACE("(%p)->(%p)\n", This, value);
2996 }
2997 
2999 {
3001  TRACE("(%p)->(%d)\n", This, value);
3003 }
3004 
3006 {
3008  TRACE("(%p)->(%p)\n", This, value);
3010 }
3011 
3013 {
3015  TRACE("(%p)->(%d)\n", This, value);
3017 }
3018 
3020 {
3022  TRACE("(%p)->(%p)\n", This, value);
3024 }
3025 
3027 {
3029  TRACE("(%p)->(%d)\n", This, value);
3031 }
3032 
3034 {
3036  TRACE("(%p)->(%p)\n", This, value);
3038 }
3039 
3041 {
3043  TRACE("(%p)->(%d)\n", This, value);
3045 }
3046 
3048 {
3050  TRACE("(%p)->(%p)\n", This, value);
3052 }
3053 
3055 {
3057  TRACE("(%p)->(%d)\n", This, value);
3059 }
3060 
3062 {
3064  TRACE("(%p)->(%p)\n", This, value);
3066 }
3067 
3069 {
3071  TRACE("(%p)->(%.2f)\n", This, value);
3073 }
3074 
3076 {
3078  TRACE("(%p)->(%p)\n", This, value);
3080 }
3081 
3083 {
3085  TRACE("(%p)->(%d)\n", This, value);
3087 }
3088 
3090 {
3092 
3093  TRACE("(%p)->(%p)\n", This, value);
3094 
3095  if (!value)
3096  return E_INVALIDARG;
3097 
3098  *value = NULL;
3099 
3100  if (!This->range) {
3101  if (This->props[FONT_NAME].str)
3102  *value = SysAllocString(This->props[FONT_NAME].str);
3103  else
3104  *value = SysAllocStringLen(NULL, 0);
3105  return *value ? S_OK : E_OUTOFMEMORY;
3106  }
3107 
3108  return textfont_getname_from_range(This->range, value);
3109 }
3110 
3112 {
3115 
3116  TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3117 
3118  v.str = value;
3119  return set_textfont_prop(This, FONT_NAME, &v);
3120 }
3121 
3123 {
3125  TRACE("(%p)->(%p)\n", This, value);
3127 }
3128 
3130 {
3132  TRACE("(%p)->(%d)\n", This, value);
3134 }
3135 
3137 {
3139  TRACE("(%p)->(%p)\n", This, value);
3141 }
3142 
3144 {
3146  TRACE("(%p)->(%.2f)\n", This, value);
3148 }
3149 
3151 {
3153  TRACE("(%p)->(%p)\n", This, value);
3155 }
3156 
3158 {
3160  TRACE("(%p)->(%d)\n", This, value);
3162 }
3163 
3165 {
3167  TRACE("(%p)->(%p)\n", This, value);
3169 }
3170 
3172 {
3174  TRACE("(%p)->(%d)\n", This, value);
3176 }
3177 
3179 {
3181  TRACE("(%p)->(%p)\n", This, value);
3183 }
3184 
3186 {
3188  TRACE("(%p)->(%.2f)\n", This, value);
3190 }
3191 
3193 {
3195  TRACE("(%p)->(%p)\n", This, value);
3197 }
3198 
3200 {
3202  TRACE("(%p)->(%d)\n", This, value);
3204 }
3205 
3207 {
3209  TRACE("(%p)->(%p)\n", This, value);
3211 }
3212 
3214 {
3216  TRACE("(%p)->(%.2f)\n", This, value);
3218 }
3219 
3221 {
3223  TRACE("(%p)->(%p)\n", This, value);
3225 }
3226 
3228 {
3230  TRACE("(%p)->(%d)\n", This, value);
3232 }
3233 
3235 {
3237  TRACE("(%p)->(%p)\n", This, value);
3239 }
3240 
3242 {
3244  TRACE("(%p)->(%d)\n", This, value);
3246 }
3247 
3249 {
3251  TRACE("(%p)->(%p)\n", This, value);
3253 }
3254 
3256 {
3258  TRACE("(%p)->(%d)\n", This, value);
3260 }
3261 
3263 {
3265  TRACE("(%p)->(%p)\n", This, value);
3267 }
3268 
3270 {
3272  TRACE("(%p)->(%d)\n", This, value);
3274 }
3275 
3277 {
3279  TRACE("(%p)->(%p)\n", This, value);
3281 }
3282 
3284 {
3286  TRACE("(%p)->(%d)\n", This, value);
3288 }
3289 
3290 static ITextFontVtbl textfontvtbl = {
3353 };
3354 
3356 {
3358 
3359  *ret = NULL;
3360  font = heap_alloc(sizeof(*font));
3361  if (!font)
3362  return E_OUTOFMEMORY;
3363 
3364  font->ITextFont_iface.lpVtbl = &textfontvtbl;
3365  font->ref = 1;
3366 
3367  if (src) {
3368  font->range = NULL;
3369  font->get_cache_enabled = TRUE;
3370  font->set_cache_enabled = TRUE;
3371  memcpy(&font->props, &src->props, sizeof(font->props));
3372  if (font->props[FONT_NAME].str)
3373  font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3374  }
3375  else {
3376  font->range = range;
3377  ITextRange_AddRef(range);
3378 
3379  /* cache current properties */
3380  font->get_cache_enabled = FALSE;
3381  font->set_cache_enabled = FALSE;
3383  }
3384 
3385  *ret = &font->ITextFont_iface;
3386  return S_OK;
3387 }
3388 
3389 /* ITextPara */
3391 {
3393 
3394  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3395 
3396  if (IsEqualIID(riid, &IID_ITextPara) ||
3399  {
3400  *ppv = iface;
3401  ITextPara_AddRef(iface);
3402  return S_OK;
3403  }
3404 
3405  *ppv = NULL;
3406  return E_NOINTERFACE;
3407 }
3408 
3410 {
3413  TRACE("(%p)->(%u)\n", This, ref);
3414  return ref;
3415 }
3416 
3418 {
3421 
3422  TRACE("(%p)->(%u)\n", This, ref);
3423 
3424  if (!ref)
3425  {
3426  ITextRange_Release(This->range);
3427  heap_free(This);
3428  }
3429 
3430  return ref;
3431 }
3432 
3434 {
3435  if (This->range)
3436  {
3437  ITextRangeImpl *rng = impl_from_ITextRange(This->range);
3438  return rng->child.reole;
3439  }
3440  return NULL;
3441 }
3442 
3444 {
3446  TRACE("(%p)->(%p)\n", This, pctinfo);
3447  *pctinfo = 1;
3448  return S_OK;
3449 }
3450 
3452  ITypeInfo **ppTInfo)
3453 {
3455  HRESULT hr;
3456 
3457  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3458 
3459  hr = get_typeinfo(ITextPara_tid, ppTInfo);
3460  if (SUCCEEDED(hr))
3461  ITypeInfo_AddRef(*ppTInfo);
3462  return hr;
3463 }
3464 
3466  LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3467 {
3469  ITypeInfo *ti;
3470  HRESULT hr;
3471 
3472  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3473  cNames, lcid, rgDispId);
3474 
3475  hr = get_typeinfo(ITextPara_tid, &ti);
3476  if (SUCCEEDED(hr))
3477  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3478  return hr;
3479 }
3480 
3482  ITextPara *iface,
3483  DISPID dispIdMember,
3484  REFIID riid,
3485  LCID lcid,
3486  WORD wFlags,
3487  DISPPARAMS *pDispParams,
3488  VARIANT *pVarResult,
3489  EXCEPINFO *pExcepInfo,
3490  UINT *puArgErr)
3491 {
3493  ITypeInfo *ti;
3494  HRESULT hr;
3495 
3496  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3497  debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3498  pExcepInfo, puArgErr);
3499 
3500  hr = get_typeinfo(ITextPara_tid, &ti);
3501  if (SUCCEEDED(hr))
3502  hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3503  return hr;
3504 }
3505 
3507 {
3509  FIXME("(%p)->(%p)\n", This, ret);
3510 
3511  if (!para_get_reole(This))
3512  return CO_E_RELEASED;
3513 
3514  return E_NOTIMPL;
3515 }
3516 
3518 {
3520  FIXME("(%p)->(%p)\n", This, para);
3521 
3522  if (!para_get_reole(This))
3523  return CO_E_RELEASED;
3524 
3525  return E_NOTIMPL;
3526 }
3527 
3529 {
3531  FIXME("(%p)->(%p)\n", This, ret);
3532 
3533  if (!para_get_reole(This))
3534  return CO_E_RELEASED;
3535 
3536  return E_NOTIMPL;
3537 }
3538 
3540 {
3542  FIXME("(%p)->(%p %p)\n", This, para, ret);
3543 
3544  if (!para_get_reole(This))
3545  return CO_E_RELEASED;
3546 
3547  return E_NOTIMPL;
3548 }
3549 
3551 {
3553  FIXME("(%p)->(%d)\n", This, value);
3554 
3555  if (!para_get_reole(This))
3556  return CO_E_RELEASED;
3557 
3558  return E_NOTIMPL;
3559 }
3560 
3562 {
3564  FIXME("(%p)->(%p)\n", This, value);
3565 
3566  if (!para_get_reole(This))
3567  return CO_E_RELEASED;
3568 
3569  return E_NOTIMPL;
3570 }
3571 
3573 {
3575  FIXME("(%p)->(%d)\n", This, value);
3576 
3577  if (!para_get_reole(This))
3578  return CO_E_RELEASED;
3579 
3580  return E_NOTIMPL;
3581 }
3582 
3584 {
3586  static int once;
3587 
3588  if (!once++) FIXME("(%p)->(%p)\n", This, value);
3589 
3590  if (!para_get_reole(This))
3591  return CO_E_RELEASED;
3592 
3593  return E_NOTIMPL;
3594 }
3595 
3597 {
3599  FIXME("(%p)->(%d)\n", This, value);
3600 
3601  if (!para_get_reole(This))
3602  return CO_E_RELEASED;
3603 
3604  return E_NOTIMPL;
3605 }
3606 
3608 {
3610  FIXME("(%p)->(%p)\n", This, value);
3611 
3612  if (!para_get_reole(This))
3613  return CO_E_RELEASED;
3614 
3615  return E_NOTIMPL;
3616 }
3617 
3619 {
3621  FIXME("(%p)->(%d)\n", This, value);
3622 
3623  if (!para_get_reole(This))
3624  return CO_E_RELEASED;
3625 
3626  return E_NOTIMPL;
3627 }
3628 
3630 {
3632  FIXME("(%p)->(%p)\n", This, value);
3633 
3634  if (!para_get_reole(This))
3635  return CO_E_RELEASED;
3636 
3637  return E_NOTIMPL;
3638 }
3639 
3641 {
3643  FIXME("(%p)->(%p)\n", This, value);
3644 
3645  if (!para_get_reole(This))
3646  return CO_E_RELEASED;
3647 
3648  return E_NOTIMPL;
3649 }
3650 
3652 {
3654  FIXME("(%p)->(%d)\n", This, value);
3655 
3656  if (!para_get_reole(This))
3657  return CO_E_RELEASED;
3658 
3659  return E_NOTIMPL;
3660 }
3661 
3663 {
3665  FIXME("(%p)->(%p)\n", This, value);
3666 
3667  if (!para_get_reole(This))
3668  return CO_E_RELEASED;
3669 
3670  return E_NOTIMPL;
3671 }
3672 
3674 {
3676  FIXME("(%p)->(%d)\n", This, value);
3677 
3678  if (!para_get_reole(This))
3679  return CO_E_RELEASED;
3680 
3681  return E_NOTIMPL;
3682 }
3683 
3685 {
3687  FIXME("(%p)->(%p)\n", This, value);
3688 
3689  if (!para_get_reole(This))
3690  return CO_E_RELEASED;
3691 
3692  return E_NOTIMPL;
3693 }
3694 
3696 {
3698  FIXME("(%p)->(%p)\n", This, value);
3699 
3700  if (!para_get_reole(This))
3701  return CO_E_RELEASED;
3702 
3703  return E_NOTIMPL;
3704 }
3705 
3707 {
3709  FIXME("(%p)->(%p)\n", This, value);
3710 
3711  if (!para_get_reole(This))
3712  return CO_E_RELEASED;
3713 
3714  return E_NOTIMPL;
3715 }
3716 
3718 {
3720  FIXME("(%p)->(%p)\n", This, value);
3721 
3722  if (!para_get_reole(This))
3723  return CO_E_RELEASED;
3724 
3725  return E_NOTIMPL;
3726 }
3727 
3729 {
3731  FIXME("(%p)->(%d)\n", This, value);
3732 
3733  if (!para_get_reole(This))
3734  return CO_E_RELEASED;
3735 
3736  return E_NOTIMPL;
3737 }
3738 
3740 {
3742  FIXME("(%p)->(%p)\n", This, value);
3743 
3744  if (!para_get_reole(This))
3745  return CO_E_RELEASED;
3746 
3747  return E_NOTIMPL;
3748 }
3749 
3751 {
3753  FIXME("(%p)->(%d)\n", This, value);
3754 
3755  if (!para_get_reole(This))
3756  return CO_E_RELEASED;
3757 
3758  return E_NOTIMPL;
3759 }
3760 
3762 {
3764  FIXME("(%p)->(%p)\n", This, value);
3765 
3766  if (!para_get_reole(This))
3767  return CO_E_RELEASED;
3768 
3769  return E_NOTIMPL;
3770 }
3771 
3773 {
3775  FIXME("(%p)->(%d)\n", This, value);
3776 
3777  if (!para_get_reole(This))
3778  return CO_E_RELEASED;
3779 
3780  return E_NOTIMPL;
3781 }
3782 
3784 {
3786  FIXME("(%p)->(%p)\n", This, value);
3787 
3788  if (!para_get_reole(This))
3789  return CO_E_RELEASED;
3790 
3791  return E_NOTIMPL;
3792 }
3793 
3795 {
3797  FIXME("(%p)->(%.2f)\n", This, value);
3798 
3799  if (!para_get_reole(This))
3800  return CO_E_RELEASED;
3801 
3802  return E_NOTIMPL;
3803 }
3804 
3806 {
3808  FIXME("(%p)->(%p)\n", This, value);
3809 
3810  if (!para_get_reole(This))
3811  return CO_E_RELEASED;
3812 
3813  return E_NOTIMPL;
3814 }
3815 
3817 {
3819  FIXME("(%p)->(%d)\n", This, value);
3820 
3821  if (!para_get_reole(This))
3822  return CO_E_RELEASED;
3823 
3824  return E_NOTIMPL;
3825 }
3826 
3828 {
3830  FIXME("(%p)->(%p)\n", This, value);
3831 
3832  if (!para_get_reole(This))
3833  return CO_E_RELEASED;
3834 
3835  return E_NOTIMPL;
3836 }
3837 
3839 {
3841  FIXME("(%p)->(%d)\n", This, value);
3842 
3843  if (!para_get_reole(This))
3844  return CO_E_RELEASED;
3845 
3846  return E_NOTIMPL;
3847 }
3848 
3850 {
3852  FIXME("(%p)->(%p)\n", This, value);
3853 
3854  if (!para_get_reole(This))
3855  return CO_E_RELEASED;
3856 
3857  return E_NOTIMPL;
3858 }
3859 
3861 {
3863  FIXME("(%p)->(%d)\n", This, value);
3864 
3865  if (!para_get_reole(This))
3866  return CO_E_RELEASED;
3867 
3868  return E_NOTIMPL;
3869 }
3870 
3872 {
3874  FIXME("(%p)->(%p)\n", This, value);
3875 
3876  if (!para_get_reole(This))
3877  return CO_E_RELEASED;
3878 
3879  return E_NOTIMPL;
3880 }
3881 
3883 {
3885  FIXME("(%p)->(%.2f)\n", This, value);
3886 
3887  if (!para_get_reole(This))
3888  return CO_E_RELEASED;
3889 
3890  return E_NOTIMPL;
3891 }
3892 
3893 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3894 {
3896  FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3897 
3898  if (!para_get_reole(This))
3899  return CO_E_RELEASED;
3900 
3901  return E_NOTIMPL;
3902 }
3903 
3904 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3905 {
3907  FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3908 
3909  if (!para_get_reole(This))
3910  return CO_E_RELEASED;
3911 
3912  return E_NOTIMPL;
3913 }
3914 
3916 {
3918  FIXME("(%p)->(%p)\n", This, value);
3919 
3920  if (!para_get_reole(This))
3921  return CO_E_RELEASED;
3922 
3923  return E_NOTIMPL;
3924 }
3925 
3927 {
3929  FIXME("(%p)->(%.2f)\n", This, value);
3930 
3931  if (!para_get_reole(This))
3932  return CO_E_RELEASED;
3933 
3934  return E_NOTIMPL;
3935 }
3936 
3938 {
3940  FIXME("(%p)->(%p)\n", This, value);
3941 
3942  if (!para_get_reole(This))
3943  return CO_E_RELEASED;
3944 
3945  return E_NOTIMPL;
3946 }
3947 
3949 {
3951  FIXME("(%p)->(%.2f)\n", This, value);
3952 
3953  if (!para_get_reole(This))
3954  return CO_E_RELEASED;
3955 
3956  return E_NOTIMPL;
3957 }
3958 
3960 {
3962  FIXME("(%p)->(%p)\n", This, value);
3963 
3964  if (!para_get_reole(This))
3965  return CO_E_RELEASED;
3966 
3967  return E_NOTIMPL;
3968 }
3969 
3971 {
3973  FIXME("(%p)->(%d)\n", This, value);
3974 
3975  if (!para_get_reole(This))
3976  return CO_E_RELEASED;
3977 
3978  return E_NOTIMPL;
3979 }
3980 
3982 {
3984  FIXME("(%p)->(%p)\n", This, value);
3985 
3986  if (!para_get_reole(This))
3987  return CO_E_RELEASED;
3988 
3989  return E_NOTIMPL;
3990 }
3991 
3992 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3993 {
3995  FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
3996 
3997  if (!para_get_reole(This))
3998  return CO_E_RELEASED;
3999 
4000  return E_NOTIMPL;
4001 }
4002 
4004 {
4006  FIXME("(%p)\n", This);
4007 
4008  if (!para_get_reole(This))
4009  return CO_E_RELEASED;
4010 
4011  return E_NOTIMPL;
4012 }
4013 
4015 {
4017  FIXME("(%p)->(%.2f)\n", This, pos);
4018 
4019  if (!para_get_reole(This))
4020  return CO_E_RELEASED;
4021 
4022  return E_NOTIMPL;
4023 }
4024 
4025 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader)
4026 {
4027  ITextParaImpl *This =